André Markwalder wrote:
Thanks for the suggestions ;-)
We test the server with a massive multithreaded test but only on one
machine. You're right we should test the server on multiple clients. I
will do this.
Thanks for your help. We try to reproduce the error in our environment.
I will let you know if we find something concerning OJB.
ok! Think this issue is important for other OJB user too.
One last question. When will OJB 1.0.4 be available?
I know a new release is overdue, but there is a nasty bug (OJB-63) which
should be fixed before next release (Jakob is working on this stuff).
Except for OJB-63 and some documentation updates 1.0.4 is ready for release.
If possible please get the latest version from CVS (OJB_1_0_RELEASE
branch) and run it against your test-suite (to check the refactored PB
handling in managed environments).
regards,
Armin
Best regards
André
Armin Waibel wrote:
André Markwalder wrote:
I tried it with an eviction thread enabled same result, everything
works fine on our installation. I changed some settings on our
websphere and try it again.
How do you test your installation - running a massive multithreaded
test? I recommend to write such a test (and if possible to run
physical different clients against the server)
Did you have a look at the code I posted in an earlier mail? Did you
see something special how we obtain the broker in the beans?
Seems ok.
Only minor suggestions.
public static AesPersistenceBrokerFactory getInstance()
the well known singleton problem, it's not guaranteed that only one
AesPersistenceBrokerFactory will be created on startup (thus it could
happen that OJB's PBF is instantiated twice too). But this shouldn't
be a problem (in OJB we use this "wrong" singleton pattern too).
private PersistenceBroker getBroker(int retry)
Before returning the PB instance all listeners will be removed and
then new temporary listener are added. It's not recommended to remove
all listener (permanent and temporary) when lookup a new PB instance,
because OJB add some listener too (e.g. the caching implementations)
and this call will remove these listener instances.
I know in 1.0.3 is a bug caused by the RsIterator class which increase
the temporary listener (on each query execution) while using the PB
instance (fixed in upcoming 1.0.4), but OJB remove all temporary
listener by itself on PB.close() call.
regards,
Armin
I attached the code again after this email.
Thanks a lot and best regards
André
Every bean method gets the broker in the following manner:
PersistenceBroker broker = null;
try {
// get broker
broker = getBroker();
// ... processing
// here we instantiate new classes which uses the broker
// we pass the broker via the constructor to the class
}
catch (....Exception e) {
// AesTransactionException is a RuntimeException so the
database actions will be rolled back
throw new AesTransactioinException(....);
}
finally {
releaseBroker(broker);
}
getBroker():
AesPersistenceBrokerFactory.getInstance().getBroker()
releaseBroker();
AesPersistenceBrokerFactory.getInstance().releaseBroker(broker);
AesPersistenceBrokerFactory (Singleton implementation based on a
unique app name at the moment it's only one app accessing the beans):
public static AesPersistenceBrokerFactory getInstance() {
String appName =
AesServerProperties.getInstance().getProperty(AesServerProperties.PROP_AES_APPLICATION);
AesPersistenceBrokerFactory instance =
(AesPersistenceBrokerFactory)instances.get(appName);
if (instance==null) {
instance = new AesPersistenceBrokerFactory();
instances.put(appName,instance);
}
return instance;
}
public PersistenceBroker getBroker() {
return getBroker(0);
}
private PersistenceBroker getBroker(int retry) {
PersistenceBroker broker = null;
try {
if (retry > 0) {
log.warn("Tried to retrieve broker more than once (" +
retry + "). Increase connection pool max size and OJB maxActive
settings.");
}
// here the call will be blocked till timeout
broker = pbf.defaultPersistenceBroker();
} catch (PBFactoryException e) {
if (retry < retryAttempts) {
return getBroker(retry+1);
}
throw new AesTransactionException(new
AesOjbPBNotAvailableException("No more Persistence Broker are
available ..."),this.getClass());
}
broker.removeAllListeners();
broker.addListener(new AesPBLifeCycleListener());
broker.addListener(new AesPBStateListener());
return broker;
}
public void releaseBroker(PersistenceBroker broker) {
if (broker != null) {
broker.close();
}
broker = null;
}
Armin Waibel wrote:
André Markwalder wrote:
We changed only the settings for maxActive to 50 (not 100) and
whenExhaustedAction to 1 (not 0). Attached the section about the
PersistenceBroker pool configuration in OJB.properties file.
I think we have at the moment 50 db connections configured in the
connection pool from websphere. We changed the maxActive settings
according to this.
Is this wrong? I read somewhere that the maxActive settings have to
be greater or equal to the db connections in the connection pool.
It's correct (each PB instance use 0 or 1 connection instance, so
the connection-pool should never exhaust because OJB doesn't use
more than 50 broker instances).
This is really interesting in the commons-pool bug report the
reporter mentioned the problem (of negative active objects) was
caused by the eviction thread, but your customer have the same
problem without using this feature.
regards,
Armin
regards
André
#----------------------------------------------------------------------------------------
# PersistenceBroker pool
#----------------------------------------------------------------------------------------
# PersistenceBroker pool configuration
# This pool uses the jakarta-commons-pool api.
# There you can find things described in detail.
#
# maximum number of brokers that can be borrowed from the
# pool at one time. When non-positive, there is no limit.
maxActive=50
#
# controls the maximum number of brokers that can sit idle in the
# pool (per key) at any time. When non-positive, there is no limit
maxIdle=-1
#
# max time block to get broker instance from pool, after that
exception is thrown.
# When non-positive, block till last judgement
maxWait=2000
#
# indicates how long the eviction thread should sleep before "runs"
of examining
# idle objects. When non-positive, no eviction thread will be
launched.
timeBetweenEvictionRunsMillis=-1
#
# specifies the minimum amount of time that an broker may sit idle
# in the pool before it is eligable for eviction due to idle time.
# When non-positive, no object will be dropped from the pool due
# to idle time alone (depends on timeBetweenEvictionRunsMillis > 0)
minEvictableIdleTimeMillis=1000000
#
# specifies the behaviour of the pool when broker capacity is
# exhausted (see maxActive above)
# 0 - fail
# 1 - block
# 2 - grow
whenExhaustedAction=1
Armin Waibel wrote:
André Markwalder wrote:
Hi Armin,
Sorry for the disturbance again. I saw in our log files from the
customer that active persistence brokers is negative (-1). How
could that happen?
Normally never. The active persistence brokers count is direct
read from the used commons-pool instance. Seems this problem was
already reported for commons-pool
http://issues.apache.org/bugzilla/show_bug.cgi?id=35617
I don't know if this bug could cause more side-effects, e.g.
returning the same instance twice.
Did you modify the settings of section "PersistenceBroker pool" in
OJB.properties file (except the 'whenExhaustedAction' property),
e.g. enable the eviction thread "timeBetweenEvictionRunsMillis"?
regards,
Armin
Thanks and best regards
André
Armin Waibel wrote:
André Markwalder wrote:
The release we shipped to the customer before had these
problems as well, but not as often as with the new release.
Between these two releases we changed the behaviour of getting
the broker and did some business logic on the server. In the
first release we configured the persistence broker factory to
fail if no persistence broker is available. In the new release
we block (whenExhaustedAction=1) until a new broker is
available and retry till we get a new broker and after a
configurable amount of retries we throw an exception. Could it
be possible that this mechanism could trigger the NPE (That the
broker will be closed) ?
If the PBF and commons-pool (used to pool the PB instances) take
care of concurrency there shouldn't be a problem. Currently method
PBF.createPersistenceBroker(PBKey pbKey)
is not synchronized, because it only lookup the pool and
commons-pool use a synchronized method to borrow objects.
We did the above mentionend mechanism because we have some
database queries which takes a bit longer to complete and the
connection pool configured on websphere allows only 10
connections. We have about 200 user on the system and
concurrently about 5 user access. That's also the reason why we
mixed the tx declaration of some methods. Typically if we only
read from the database, we don't have to obtain a transactional
context. These methods have the declaration "Not Supported".
Other methods which require a transaction (if we write to the
database) have the declaration "Required". The transaction
manager times out after 120 seconds. Some bigger reports take
more than 120 seconds to complete. So we have to speed up these
reports or leave the "Not Supported" declaration in place.
We have an own implementation of the persistence broker. We
extend the PersistenceBrokerImpl and do some additional things
in pb.store(), pb.delete(), pb.retrieveAllReferences() and
pb.retrieveReference(). We had some problems with the proxies
configured in the descriptor repository. We configured our
persistence broker in OJB.properties file. Perhaps something
went wrong with the pb or tx handles. Could this own
implementation result in an earlier close of the persistence
broker?
Well! Don't ask me ;-)
So you are using PersistenceBrokerFactorySyncImpl with your own
PB implementation. I don't know about the modifications you did,
but normally changes in pb.store(), pb.delete(),
pb.retrieveAllReferences() and pb.retrieveReference() should not
affect the behavior of PB.close method or
PoolablePersistenceBroker. Did you modify any of the classes
handling proxy objects?
Is it possible that two users can hold the same persistence
broker?
The PB-api is not threadsafe, so sharing of PB instances is not
allowed, each thread have to operate on his own PB instance.
When user one e.g closes the persistence broker and user two
operates on the closed persistence broker this NPE could happen.
right, I user share a PB instance this could happen. In OJB
test-suite are many multi-threaded tests (plus separate
multithreaded session bean tests) and such a NPE (so far ;-))
never happens.
regards,
Armin
Thanks and best regards
André
Armin Waibel wrote:
Hi Andrè,
André Markwalder wrote:
Hi Armin,
You wrote in the answer for Colin that always a running
(JTA)tx is expected. Does that mean, when we use OJB in a
managed environment (e.g. WebSphere) and use declarative tx,
the declaration of "Not Supported" on method level or even on
bean level is not allowed when we use OJB (We use OJB 1.0.3)?
I must admit that (currently) we don't have a test-case to
check OJB's behavior when using "Not Supported"
tx-demarcation. In upcoming 1.0.4 a minor refactoring was done
(regarding the PB behavior when OJB can't find a running JTA-tx).
We experienced NullPointerExceptions on
pb.getClassDescriptor() (DescriptorRepository is null on the
pb). I had a look at the source code and saw that this only
happens when the broker has been closed (Sets
DescriptorRepository to null).
yep, such a NPE should never happen. It could only happen when
you operate on a closed PB instance (a PB instance already
returned to PB-pool), when lookup a PB instance from the pool,
the current used DescriptorRepository instance will be set by
the pool.
We have a mix of tx declaration (Bean tx: Required, some
methods: Not Supported). I saw also that the broker is
closed when a transaction is finished. We always close the
brokers after we used it (try/finally block).
The PB.close() call at the end of each session bean method is
recommended, because this will close the current used PB
handle (a wrapper class around the real poolable PB instance),
the real PB instance is only closed when OJB isn't run within
an active JTA-tx, else the PB instance is closed on tx end.
Is it possible that the mix of tx declarations can cause the
NPE on pb.getClassDescriptor()?
Maybe.... sorry, I never got such a NPE. Could you change the
declarative tx demarcation to "required" and run the tests
again (without mixed tx) - what happen to the NPE?
regards,
Armin
Regards
André
Armin Waibel wrote:
Hi Colin,
> What I want to do is have just a _single_ module using the
XA PB for it's
> transactional operations, while the rest use the default
PB. However when I
> set my project up as above I get errors whenever I use
_any_ broker to do
> non-JTA transaction demarcation:
>
It's not recommended to mix tx demarcation strategies (OJB's
PB-tx and the JTA-api of the appServer).
In managed environments OJB expect that all transaction
demarcation is delegated to the JTA-api. Thus you always
have to use the JTA-api (with both datasources defined in
repository file), either via declarative tx (in the
descriptor of your session bean) or programmatic tx (lookup
UserTransaction).
The only problem with OJB 1.0.3 is that in managed
environment always a running (JTA)tx is expected. Thus you
need for all operations JTA tx-demarcation.
We try fix this in upcoming 1.0.4 (CVS OJB_1_0_RELEASE
branch) by differentiate between managed session (when a
JTA-tx is active) and non-managed session (no JTA-tx)
(In 1.0.4 it's not allowed to use
ConnectionFactoryManagedImpl when performing queries without
tx-demarcation).
regards,
Armin
Colin O'Toole wrote:
Hi there,
I am using OJB in a j2ee app running on weblogic. There is
one section of
the code that needs to be part of a JTA transaction
(database access via the
PB API and also some JMS writes).
I have the following:
1. In OJB.properties:
-
PersistenceBrokerFactoryClass=org.apache.ojb.broker.core.PersistenceBrokerFa
ctorySyncImpl
-
ConnectionFactoryClass=org.apache.ojb.broker.accesslayer.ConnectionFactoryMa
nagedImpl
-
JTATransactionManagerClass=org.apache.ojb.broker.transaction.tm.WeblogicTran
sactionManagerFactory
2. In Weblogic:
- One XA datasource
- One non-XA datasource
3. In repository_database.xml
- Two <jdbc-connection-descriptor>s, one pointing at the XA
datasource, the
other pointing at the non-XA datasource
<!-- this connection is used as the default by OJB -->
<jdbc-connection-descriptor
jcd-alias="DataSource"
default-connection="true"
platform="Oracle"
jdbc-level="2.0"
eager-release="false"
batch-mode="false"
useAutoCommit="0"
ignoreAutoCommitExceptions="true"
jndi-datasource-name="java:comp/env/myDataSource"
>
<sequence-manager
className="org.apache.ojb.broker.util.sequence.SequenceManagerNextValImpl">
<attribute attribute-name="autoNaming"
attribute-value="true"/>
</sequence-manager>
</jdbc-connection-descriptor>
<!-- This connection uses the XA data source -->
<jdbc-connection-descriptor
jcd-alias="XADataSource"
default-connection="false"
platform="Oracle"
jdbc-level="2.0"
eager-release="false"
batch-mode="false"
useAutoCommit="0"
ignoreAutoCommitExceptions="true"
jndi-datasource-name="java:comp/env/myXADataSource"
>
<sequence-manager
className="org.apache.ojb.broker.util.sequence.SequenceManagerNextValImpl">
<attribute attribute-name="autoNaming"
attribute-value="true"/>
</sequence-manager>
</jdbc-connection-descriptor>
What I want to do is have just a _single_ module using the
XA PB for it's
transactional operations, while the rest use the default
PB. However when I
set my project up as above I get errors whenever I use
_any_ broker to do
non-JTA transaction demarcation:
PersistenceBroker broker =
PersistenceBrokerFactory.defaultPersistenceBroker()
broker.beginTransaction();
broker.store(obj);
broker.commitTransaction();
Results in: java.lang.UnsupportedOperationException: In
managed environments
only JTA transaction demarcation allowed
Can anyone tell me if it's possible to do what I want, Or
am I approaching
this from the wrong angle entirely? I've failed to find
anything detailed
about OJB with JTA, so any help would be great.
Thanks,
Colin.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]