|
From: <jue...@we...> - 2004-03-10 11:42:31
|
Quoting a discussion around a issue in our JIRA: Andreas tries to = subclass JtaTransactionManager to involve TopLink UnitOfWorks and faces = some problems. I suggest that standard JtaTransactionManager should be = fine here, delegating TopLink UnitOfWork handling to transaction = synchronization (a la Hibernate SessionFactoryUtils). Read the JIRA postings below for details. I'd like to move the = discussion to the developer mailing list; after all, such a discussion = is not what JIRA was made for ;-) Juergen Threading issue with JtaTransactionFactory Created: 10/Mar/04 01:52 AM Updated: 10/Mar/04 05:21 AM =20 Project: Spring Framework=20 Component/s: SpringTX =20 Affects Version/s: 1.0 final =20 Fix Version/s: 1.0 final =20 =20 Environment: W2k, Sun SDK 1.4.2, Bea WebLogic 8.1SP1 =20 =20 Description =20 I encountered a potential threading problem concerning the = JtaTransactionFactory.=20 Currently I have a subclass of JtaTransactionFactory for purposes of = integrating TopLink on a JTS level. So far everything works fine. = However, I overrode lookupUserTransaction to provide an own = Implementation to provide access to a TopLink UnitOfWork.=20 Within WebLogic I then found that multiple UserTransaction instances = have been created, causing problems.=20 I fixed the issue by overriding the following Methods, providing = synchronized versions in my subclass:=20 - doGetTransaction=20 - lookupUserTransaction=20 - setUserTransaction (not necessary for my case, but for completion's = sake)=20 I guess, the multiple creation is due to the fact, that multiple = instances are using the singleteton Tx-Manager and the lookup is been = performed by multiple threads on SessionBean-initilization.=20 Since this seems to me a general issue, I propose to provide necessary = synchronizations within the base type, if possible. Probably there are = similar issues with the "TransactionManager" property as well.=20 I know about the J2EE Spec discouraging the use of synchronization, but = here it seems to be unavoidable.=20 Regards,=20 Andreas=20 P.S.: Besides that, a copy&paste issue=20 The error message in JtaTransactionManager#lookupTransactionManager is = wrong, referring to the UserTransaction instead of the = TransactionManager=20 =20 =20 Comments Change History =20 Juergen Hoeller [ 10/Mar/04 02:16 AM ] Delete [ Permlink ] =20 JtaTransactionnManager looks up the UserTransaction and the = TransactionManager in its afterPropertiesSet method, invoked once on = initialization of the transaction manager bean. I don't see how multiple = UserTransaction instances can be created here: The located = UserTransaction is kept in an instance field of JtaTransactionManager, = fetched from there by doGetTransaction.=20 What kind of UserTransaction are you returning from your overridden = lookupUserTransaction method? Note that a JTA UserTransaction is a = shared object that works with ThreadLocals underneath, while a TopLink = UnitOfWork is just for use by a single thread. The UnitOfWork is closer = to a JDBC Connection or Hibernate Transaction than to a JTA = UserTransaction. So I guess the problem is your subclass of = JtaTransactionManager.=20 I haven't thought about Spring/JTA/TopLink integration in detail, but it = should be possible to achieve this similar to Spring's Hibernate = integration: You use the standard JtaTransactionManager there, with = SessionFactoryUtils auto-detecting an active transaction, binding a = Session to the TransactionSynchronizationManager, and registering a = transaction synchronization that closes the Session after transaction = completion.=20 Let's move this discussion to the developer list. Of course, please tell = me if I misunderstood something! From my point of view, the standard = JtaTransactionManager's thread-safety is fine as it is, for typical = usage with a JTA UserTransaction. Therefore, I'll close this issue if we = agree that it doesn't affect usage with standard JTA.=20 Juergen =20 =20 Andreas Senft [ 10/Mar/04 04:18 AM ] Delete [ Permlink ] =20 Hello J=FCrgen,=20 thanks for the quick response.=20 Yes I'm aware of the UserTransaction characteristics. Actually I just = return a wrapper around the "standard" UserTransaction providing = additionally the active TopLink UnitOfWork.=20 I haven't had a look at the Hibernate implementation yet. TopLink is = already configured to integrate itself with BEAs JTS, so the inheritance = from JtaTransactionManager seemed fitting.=20 Concerning the initialization issue, I think I have a clue:=20 I have several Session Beans. Also BEA is configured to populate the = pool on deployment, so multiple Instances will be created on server = startup (possibly by multiple Worker threads).=20 Each Session Bean has a POJO Handler with attached DAO and each DAO has = a reference to the single TransactionManager.=20 As it seems to me, in that case the lookup for the UserTransaction is = invoked more than once. Probably there might be a threading issue in the = configuration itself?=20 If it has no impact on "normal" JTA transactions I agree to close this = issue, since I have a workaround. If I find out more about the issue, I = will let you know.=20 Regards,=20 Andreas =20 =20 Andreas Senft [ 10/Mar/04 04:40 AM ] Delete [ Permlink ] =20 One afterthought:=20 If DefaultListableBeanFactory#preInstantiateSingletons is not invoked, I = guess the Initialization is performed lazily and thus subject of = concurrency issues?=20 Might that be an explanation?=20 Regards,=20 Andreas =20 =20 Juergen Hoeller [ 10/Mar/04 05:21 AM ] Delete [ Permlink ] =20 Actually, if you don't pre-instantiate singletons, there is indeed a = potential for race conditions - we don't recommend that for = multi-threaded environments. However, I've recently committed fixes to = the BeanFactory implementations that allow for proper lazy-init of = singletons in a multi-threaded environment.=20 So if that might be the reason for the behavior that you experience, = please pre-instantiate your singletons or use the current CVS HEAD. We = should not have to synchronize in JtaTransactionManager in any sort of = usage that I can image. It would be good to find the root cause and to = consequently avoid your current workaround.=20 How do you use your TopLink UnitOfWorks behind a UserTransaction = interface? Do you store them in ThreadLocals?=20 I really recommend checking out SessionFactoryUtils and its use of = transaction synchronization: You should be able to use the standard = JtaTransactionManager then, lazily starting and binding a TopLink = UnitOfWork at first access, committing the UnitOfWork in the = beforeCommit callback of Spring's transaction synchronization.=20 It would probably be better to move this discussion to the developer = mailing list. It's more about how to integrate TopLink than about issues = that affect standard JtaTransactionManager usage. Let's quote our = discussion there to give others a start.=20 Juergen =20 DI J=FCrgen H=F6ller Senior System Architect ______________________________________ werk3ATS - division systementwicklung werk3AT informations- und mediensysteme europaplatz 4 A - 4020 linz t. +43 (0) 732 71 65 29 502 f. +43 (0) 732 71 65 29 3 mailto:jue...@we... http://www.werk3at.com ______________________________________ werk3ATS - WIR ENTWICKELN ERFOLG |