Hi All, Wanted to post an update to this. It was indeed a locking situation. The insert on the second server was locking the row (or perhaps the page as someone tells me that db2 applies page locks). It holds the lock until a commit, which never arrives since the commit would only occur when the method call exits on the first EJB on server 1. I tried changing the attribute on the second EJB to REQUIRESNEW which starts a new transaction always and commits it as it exits and then the second method. Having done this everything works.
Can anyone tell me or point me to a resource where the manager.find on the first server is able to fetch the uncommitted entity from the context itself. I understand I have to use a distributed cache. devu213 wrote: > > Thanks Michael. However, I forgot to mention this: > > I also tried swapping the two find calls i.e do a find for the entity > persisted on the remote server first and then try and do a find for the > entity on the local server. This time it hangs on the first call itself > i.e the output now is: > > On server 1 > Cast successful > First call complete > Hang...until 60 sec > Found FirstSEPnull > Found SecondSEP784 > > Do you think it is still an isolation level problem? > > I will try having only a single find for the entity persisted on the > remote server and let you know the results. > > > > Michael Dick wrote: >> >> Sounds like DB2 is getting an exclusive lock on the row when you do the >> first find. WebSphere's default isolation level is RR which will obtain >> long >> lived locks. >> >> Unfortunately it isn't always easy to change the default in WebSphere. >> The >> recommended way is to create a resource reference in your application, >> set >> the isolation level on the resource ref, and update persistence.xml to >> use >> it (ie <jta-data-source>java:comp/env/myDataSource</jta-data-source>). >> This >> approach can be a lot of work if you have a lot of persistence units.. >> >> Another way to go is to change the default level on the WAS datasource. >> This >> has the downside of affecting everyone who uses the datasource though. To >> do >> this add at custom property as described here [1]. >> >> Either way you probably want to set the isolation to the JPA default of >> ReadCommitted. >> >> [1] http://www-01.ibm.com/support/docview.wss?rs=180&uid=swg21224492 >> >> Hope this helps, >> -mike >> >> On Thu, Jun 11, 2009 at 12:11 PM, devu213 <[email protected]> wrote: >> >>> >>> Hi, >>> >>> I have a scenario where I'm trying to run a distributed transaction >>> across >>> two websphere 6.1 app servers on two different nodes (2 physical >>> machines). >>> A stateless session bean on server 1 makes an entry to a table in the >>> database after which it calls the remote ejb on server 2 which again >>> makes >>> an entry on the same table in the same database. >>> >>> On server 1 >>> >>> @Stateless >>> @TransactionManagement(TransactionManagementType.CONTAINER) >>> @TransactionAttribute(TransactionAttributeType.REQUIRED) >>> public class ManagerBean implements Manager { >>> >>> @PersistenceContext(unitName="bs") >>> EntityManager manager; >>> >>> public void saveAgreement() { >>> //snip...get the context etc >>> >>> try { >>> SEPAgreement agreement = new SEPAgreement(786l); //the >>> entity object >>> manager.persist(agreement); >>> MyRemote remote = (MyRemote) PortableRemoteObject.narrow( >>> >>> ctx.lookup("dk.pbs.bs.functions.MyRemote"), >>> MyRemote.class); >>> System.out.println("Cast successful"); >>> >>> agreement = new SEPAgreement(7864l); >>> >>> remote.insert(agreement); >>> >>> System.out.println("First call complete"); >>> SEPAgreement agr1= manager.find(SEPAgreement.class, 786); >>> System.out.println("Found first" + agr1); >>> SEPAgreement agr2 = manager.find(SEPAgreement.class, >>> 7864); >>> System.out.println("Found second" + agr2); >>> >>> } catch (Exception e) { >>> >>> //snip >>> >>> On server 2: >>> >>> @Stateless >>> @TransactionManagement(TransactionManagementType.CONTAINER) >>> @TransactionAttribute(TransactionAttributeType.REQUIRED) >>> public class MyRemoteImpl implements MyRemote { >>> >>> @PersistenceContext(unitName="abc") >>> EntityManager manager; >>> >>> public void insert(SEPAgreement agreement) { >>> System.out.println("In remote"); >>> System.out.println("Before persist" + agreement); >>> try { >>> manager.persist(agreement); >>> manager.flush(); >>> System.out.println("After persist" + agreement); >>> } catch (Exception e) { >>> >>> >>> //snip >>> >>> In the output on server 1 it prints: >>> Cast successful >>> first call complete >>> found first SEP786 >>> >>> It then hangs until the transaction on the second server times out (for >>> some >>> strange reason) >>> >>> In the output on server 2 it prints: >>> Before persist 7864 >>> After persist 7864 >>> waits...for 60 seconds after which it gives a transaction time out >>> message. >>> >>> The thing is that the second call to manager.find"() for an object which >>> is >>> persisted in the remote call causes it to hang. If I comment out the >>> call >>> everything works fine. Also the noticeable thing is that after the >>> second >>> server gives a time out message for the transaction, I then see the >>> remaining sysouts >>> i.e >>> Found second SEPnull >>> >>> I am wondering if I'm missing something here. Although I'm not sure if >>> the >>> second find should have succeeded given that I'm not using a any sort of >>> distributed cache yet, I don't expect it to hang either. Any ideas? Find >>> the >>> code attached. >>> >>> >>> http://n2.nabble.com/file/n3063290/strangebehaviourwithadistributedtransaction_.zip >>> strangebehaviourwithadistributedtransaction_.zip >>> -- >>> View this message in context: >>> http://n2.nabble.com/Strange-behavior-with-a-distributed-transaction-tp3063290p3063290.html >>> Sent from the OpenJPA Users mailing list archive at Nabble.com. >>> >>> >> >> > > -- View this message in context: http://n2.nabble.com/Strange-behavior-with-a-distributed-transaction-tp3063290p3068061.html Sent from the OpenJPA Users mailing list archive at Nabble.com.
