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]

Reply via email to