datasource - Resin + Oracle + [Spring] + XA Transaction REQUIRES_NEW – Inner Transaction Commit Fails -
could please solve problem xa transactions on resin + oracle:
we have webapp has execute business transactions involve both oracle 11.2.0.1 , ehcache 2.7. (actually various combinations possible – 2 different oracle data sources (different schemas) with/without ehcache, etc). reason switch plain jdbc usage jta transactions demarcation.
we use: - resin jta implementation decorated spring 3.2.1 simplify transactions suspending , make use of programmatic approach transaction boundaries definition (“manual” usage of transactionmanager suspending/resuming gives problem) follows:
public void dooutertransaction() throws throwable { defaulttransactiondefinition def = new defaulttransactiondefinition(); def.setname("mytx"); def.setpropagationbehavior(transactiondefinition.propagation_requires); transactionstatus status = txmanager.gettransaction(def); connection connection = null; cache cache = null; try { cache = ...; // cache cachemanager connection = mydatasource.getconnection(); // or "datasourceutils.getconnection(mydatasource)" guarantee same dbconnection spring // business logic doinnertransaction(); // business logic txmanager.commit(status); } catch (throwable ex) { txmanager.rollback(status); throw ex; } { if (connection!=null) { connection.close(); } } } public void doinnertransaction() throws throwable { defaulttransactiondefinition def = new defaulttransactiondefinition(); def.setname("mytx"); def.setpropagationbehavior(transactiondefinition.propagation_requires_new); transactionstatus status = txmanager.gettransaction(def); connection connection = null; cache cache = null; try { cache = ...; // cache cachemanager connection = mydatasource.getconnection(); // or "datasourceutils.getconnection(mydatasource)" guarantee same dbconnection spring // business logic txmanager.commit(status); } catch (throwable ex) { txmanager.rollback(status); throw ex; } { if (connection!=null) { connection.close(); } } }
- ehcache caches configured “xa” transactions support.
resin connections pool oracle driver “oracle.jdbc.xa.client.oraclexadatasource”, configured via resin.conf follows
<database> <name>my_xa_datasource</name> <jndi-name>jdbc/my_xa</jndi-name> <driver> <type>oracle.jdbc.xa.client.oraclexadatasource</type> <url>${my_db_url}</url> <user>${my_db_username}</user> <password>${my_db_password}</password> </driver> <max-connections>50</max-connections> <max-idle-time>60s</max-idle-time> <max-active-time>24h</max-active-time> <max-overflow-connections>15</max-overflow-connections> <ping>true</ping> <ping-table>dual</ping-table> <ping-interval>240s</ping-interval> <transaction-timeout>24h</transaction-timeout> <xa>true</xa> </database>
all transactions combination of affected resources propagation level required works fine out of box. when have case outer transaction “required” , inner transaction “requires_new” – suspending outer transaction causes problems , inner transaction couldn't committed. , more - running inner transaction can see uncommited changes outer transaction looks wrong.
behavior depends on resources involved in outer , inner transactions. have following cases: 1. having ehcache access in both inner , outer transactions works fine requires_new inner one.
having ehcache access in outer transaction , db access in inner transaction works fine requires_new inner one.
case db access in outer transaction or in both transactions (no matter how many datasources involved, if datasources usage not overlaps transaction boundaries) gives following error commit of inner transaction:
_
ch.sc.common.shortagruntimeexception: org.springframework.transaction.transactionsystemexception: jta failure on commit; nested exception com.caucho.transaction.systemexceptionwrapper: xa_rmerr: resource manager error. @ ch.sc.glibs.mytest.mytestservlet.doget(mytestservlet.java:34) @ javax.servlet.http.httpservlet.service(httpservlet.java:120) @ javax.servlet.http.httpservlet.service(httpservlet.java:97) @ com.caucho.server.dispatch.servletfilterchain.dofilter(servletfilterchain.java:109) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ com.caucho.server.security.securityfilterchain.dofilter(securityfilterchain.java:132) @ com.caucho.server.webapp.webapplistenerfilterchain.dofilter(webapplistenerfilterchain.java:114) @ com.caucho.server.webapp.webappfilterchain.dofilter(webappfilterchain.java:156) @ com.caucho.server.webapp.accesslogfilterchain.dofilter(accesslogfilterchain.java:95) @ com.caucho.server.dispatch.servletinvocation.service(servletinvocation.java:289) @ com.caucho.server.http.httprequest.handlerequest(httprequest.java:838) @ com.caucho.network.listen.tcpsocketlink.dispatchrequest(tcpsocketlink.java:1309) @ com.caucho.network.listen.tcpsocketlink.handlerequest(tcpsocketlink.java:1265) @ com.caucho.network.listen.tcpsocketlink.handlerequestsimpl(tcpsocketlink.java:1249) @ com.caucho.network.listen.tcpsocketlink.handlerequests(tcpsocketlink.java:1157) @ com.caucho.network.listen.tcpsocketlink.handleaccepttaskimpl(tcpsocketlink.java:956) @ com.caucho.network.listen.connectiontask.runthread(connectiontask.java:117) @ com.caucho.network.listen.connectiontask.run(connectiontask.java:93) @ com.caucho.network.listen.socketlinkthreadlauncher.handletasks(socketlinkthreadlauncher.java:169) @ com.caucho.network.listen.tcpsocketacceptthread.run(tcpsocketacceptthread.java:61) @ com.caucho.env.thread2.resinthread2.runtasks(resinthread2.java:173) @ com.caucho.env.thread2.resinthread2.run(resinthread2.java:118) caused by: org.springframework.transaction.transactionsystemexception: jta failure on commit; nested exception com.caucho.transaction.systemexceptionwrapper: xa_rmerr: resource manager error. @ org.springframework.transaction.jta.jtatransactionmanager.docommit(jtatransactionmanager.java:1025) @ org.springframework.transaction.support.abstractplatformtransactionmanager.processcommit(abstractplatformtransactionmanager.java:754) @ org.springframework.transaction.support.abstractplatformtransactionmanager.commit(abstractplatformtransactionmanager.java:723) @ ch.sc.glibs.mytest.mytxtest.test3(mytxtest.java:155) @ ch.sc.glibs.mytest.mytxtest.domaincomplextx(mytxtest.java:81) @ ch.sc.glibs.mytest.mytxtest.dotxtest(mytxtest.java:50) @ ch.sc.glibs.mytest.mytxtest__resinscopeproxy.dotxtest(unknown source) @ ch.sc.glibs.mytest.mytestservlet.doget(mytestservlet.java:32) @ javax.servlet.http.httpservlet.service(httpservlet.java:120) @ javax.servlet.http.httpservlet.service(httpservlet.java:97) @ com.caucho.server.dispatch.servletfilterchain.dofilter(servletfilterchain.java:109) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ com.caucho.server.security.securityfilterchain.dofilter(securityfilterchain.java:132) @ com.caucho.server.webapp.webapplistenerfilterchain.dofilter(webapplistenerfilterchain.java:114) @ com.caucho.server.webapp.webappfilterchain.dofilter(webappfilterchain.java:156) @ com.caucho.server.webapp.accesslogfilterchain.dofilter(accesslogfilterchain.java:95) @ com.caucho.server.dispatch.servletinvocation.service(servletinvocation.java:289) @ com.caucho.server.http.httprequest.handlerequest(httprequest.java:838) @ com.caucho.network.listen.tcpsocketlink.dispatchrequest(tcpsocketlink.java:1309) @ com.caucho.network.listen.tcpsocketlink.handlerequest(tcpsocketlink.java:1265) @ com.caucho.network.listen.tcpsocketlink.handlerequestsimpl(tcpsocketlink.java:1249) @ com.caucho.network.listen.tcpsocketlink.handlerequests(tcpsocketlink.java:1157) @ com.caucho.network.listen.tcpsocketlink.handleaccepttaskimpl(tcpsocketlink.java:956) @ com.caucho.network.listen.connectiontask.runthread(connectiontask.java:117) @ com.caucho.network.listen.connectiontask.run(connectiontask.java:93) @ com.caucho.network.listen.socketlinkthreadlauncher.handletasks(socketlinkthreadlauncher.java:169) @ com.caucho.network.listen.tcpsocketacceptthread.run(tcpsocketacceptthread.java:61) @ com.caucho.env.thread2.resinthread2.runtasks(resinthread2.java:173) @ com.caucho.env.thread2.resinthread2.run(resinthread2.java:118) caused by: com.caucho.transaction.systemexceptionwrapper: xa_rmerr: resource manager error. @ com.caucho.transaction.transactionimpl.heuristicexception(transactionimpl.java:1040) @ com.caucho.transaction.transactionimpl.commitresources(transactionimpl.java:931) @ com.caucho.transaction.transactionimpl.commit(transactionimpl.java:886) @ com.caucho.transaction.transactionmanagerimpl.commit(transactionmanagerimpl.java:324) @ com.caucho.transaction.usertransactionimpl.commit(usertransactionimpl.java:363) @ com.caucho.transaction.usertransactionproxy.commit(usertransactionproxy.java:171) @ org.springframework.transaction.jta.jtatransactionmanager.docommit(jtatransactionmanager.java:1009) @ org.springframework.transaction.support.abstractplatformtransactionmanager.processcommit(abstractplatformtransactionmanager.java:754) @ org.springframework.transaction.support.abstractplatformtransactionmanager.commit(abstractplatformtransactionmanager.java:723) @ ch.sc.glibs.mytest.mytxtest.test3(mytxtest.java:155) @ ch.sc.glibs.mytest.mytxtest.domaincomplextx(mytxtest.java:81) @ ch.sc.glibs.mytest.mytxtest.dotxtest(mytxtest.java:50) @ ch.sc.glibs.mytest.mytxtest__resinscopeproxy.dotxtest(unknown source) @ ch.sc.glibs.mytest.mytestservlet.doget(mytestservlet.java:32) @ javax.servlet.http.httpservlet.service(httpservlet.java:120) @ javax.servlet.http.httpservlet.service(httpservlet.java:97) @ com.caucho.server.dispatch.servletfilterchain.dofilter(servletfilterchain.java:109) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ com.caucho.server.security.securityfilterchain.dofilter(securityfilterchain.java:132) @ com.caucho.server.webapp.webapplistenerfilterchain.dofilter(webapplistenerfilterchain.java:114) @ com.caucho.server.webapp.webappfilterchain.dofilter(webappfilterchain.java:156) @ com.caucho.server.webapp.accesslogfilterchain.dofilter(accesslogfilterchain.java:95) @ com.caucho.server.dispatch.servletinvocation.service(servletinvocation.java:289) @ com.caucho.server.http.httprequest.handlerequest(httprequest.java:838) @ com.caucho.network.listen.tcpsocketlink.dispatchrequest(tcpsocketlink.java:1309) @ com.caucho.network.listen.tcpsocketlink.handlerequest(tcpsocketlink.java:1265) @ com.caucho.network.listen.tcpsocketlink.handlerequestsimpl(tcpsocketlink.java:1249) @ com.caucho.network.listen.tcpsocketlink.handlerequests(tcpsocketlink.java:1157) @ com.caucho.network.listen.tcpsocketlink.handleaccepttaskimpl(tcpsocketlink.java:956) @ com.caucho.network.listen.connectiontask.runthread(connectiontask.java:117) @ com.caucho.network.listen.connectiontask.run(connectiontask.java:93) @ com.caucho.network.listen.socketlinkthreadlauncher.handletasks(socketlinkthreadlauncher.java:169) @ com.caucho.network.listen.tcpsocketacceptthread.run(tcpsocketacceptthread.java:61) @ com.caucho.env.thread2.resinthread2.runtasks(resinthread2.java:173) @ com.caucho.env.thread2.resinthread2.run(resinthread2.java:118) caused by: oracle.jdbc.xa.oraclexaexception @ oracle.jdbc.xa.oraclexaresource.checkerror(oraclexaresource.java:1110) @ oracle.jdbc.xa.client.oraclexaresource.end(oraclexaresource.java:436) @ com.caucho.sql.disjointxaresource.end(disjointxaresource.java:105) @ com.caucho.env.dbpool.managedpoolitem.endresource(managedpoolitem.java:1017) @ com.caucho.env.dbpool.managedpoolitem.commit(managedpoolitem.java:957) @ com.caucho.transaction.transactionimpl.commitresources(transactionimpl.java:924) @ com.caucho.transaction.transactionimpl.commit(transactionimpl.java:886) @ com.caucho.transaction.transactionmanagerimpl.commit(transactionmanagerimpl.java:324) @ com.caucho.transaction.usertransactionimpl.commit(usertransactionimpl.java:363) @ com.caucho.transaction.usertransactionproxy.commit(usertransactionproxy.java:171) @ org.springframework.transaction.jta.jtatransactionmanager.docommit(jtatransactionmanager.java:1009) @ org.springframework.transaction.support.abstractplatformtransactionmanager.processcommit(abstractplatformtransactionmanager.java:754) @ org.springframework.transaction.support.abstractplatformtransactionmanager.commit(abstractplatformtransactionmanager.java:723) @ ch.sc.glibs.mytest.mytxtest.test3(mytxtest.java:155) @ ch.sc.glibs.mytest.mytxtest.domaincomplextx(mytxtest.java:81) @ ch.sc.glibs.mytest.mytxtest.dotxtest(mytxtest.java:50) @ ch.sc.glibs.mytest.mytxtest__resinscopeproxy.dotxtest(unknown source) @ ch.sc.glibs.mytest.mytestservlet.doget(mytestservlet.java:32) @ javax.servlet.http.httpservlet.service(httpservlet.java:120) @ javax.servlet.http.httpservlet.service(httpservlet.java:97) @ com.caucho.server.dispatch.servletfilterchain.dofilter(servletfilterchain.java:109) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ ch.sc.common.http.filters.regexpfilteringproxyfilter.dofilter(regexpfilteringproxyfilter.java:65) @ com.caucho.server.dispatch.filterfilterchain.dofilter(filterfilterchain.java:89) @ com.caucho.server.security.securityfilterchain.dofilter(securityfilterchain.java:132) @ com.caucho.server.webapp.webapplistenerfilterchain.dofilter(webapplistenerfilterchain.java:114) @ com.caucho.server.webapp.webappfilterchain.dofilter(webappfilterchain.java:156) @ com.caucho.server.webapp.accesslogfilterchain.dofilter(accesslogfilterchain.java:95) @ com.caucho.server.dispatch.servletinvocation.service(servletinvocation.java:289) @ com.caucho.server.http.httprequest.handlerequest(httprequest.java:838) @ com.caucho.network.listen.tcpsocketlink.dispatchrequest(tcpsocketlink.java:1309) @ com.caucho.network.listen.tcpsocketlink.handlerequest(tcpsocketlink.java:1265) @ com.caucho.network.listen.tcpsocketlink.handlerequestsimpl(tcpsocketlink.java:1249) @ com.caucho.network.listen.tcpsocketlink.handlerequests(tcpsocketlink.java:1157) @ com.caucho.network.listen.tcpsocketlink.handleaccepttaskimpl(tcpsocketlink.java:956) @ com.caucho.network.listen.connectiontask.runthread(connectiontask.java:117) @ com.caucho.network.listen.connectiontask.run(connectiontask.java:93) @ com.caucho.network.listen.socketlinkthreadlauncher.handletasks(socketlinkthreadlauncher.java:169) @ com.caucho.network.listen.tcpsocketacceptthread.run(tcpsocketacceptthread.java:61) @ com.caucho.env.thread2.resinthread2.runtasks(resinthread2.java:173) @ com.caucho.env.thread2.resinthread2.run(resinthread2.java:118)
internally see ora-25352 “no current transaction” “the user session not attached transaction” during prepare commit phase (call oracle java_xa.prepare returns error code). looks if during inner transaction commit application reason involves resources (datasource) affected in outer transaction seems incorrect because no db usage in inner transaction expect no call oracle.
the worst thing using apache dbcp pool instead of resin pool implementation solves problem… usage of atomikos (both transactionmanager implementation , connections pool implementation) works fine. both mentioned implementations have own problem.
at moment suppose having problem db pool or xa driver configuration… problem linked enhancements using local transactions instead of global, etc? tried various resources definition (database, resource-ref), used “xa-forbid-same-rm”, switched off spring transaction synchronization, tried use transactionmanager manually suspend/resume transaction, etc - no luck.
any ideas/solutions welcome!
combination resin/spring/oracle/xa transactions works perfectly. key thing here work correctly db connections.
all db connections must opened inside transaction. in case resource enlisted transaction implicitly. our example code so.
the problem left db connection open when started new transaction. means db connection provided resin's db pool (aka userconnection) hadn't been returned pool before beginning new transaction. reason resin transactionmanager implementation added unreturned db connection list of resources used in inner transaction implicitly. , commit of inner transaction failed because oracle knows db connection has been used in outer uncommitted yet transaction.
one can safely return db connection pool. after execution of inner transaction (where uncommitted changes not seen because resin provide new db connection inside new transaction) may ask again db connection in outer transaction , db connection same 1 before starting inner transaction, see uncommitted changes. resin's connections pool provided connection associated current usertransaction.
one more important thing - if use spring connection data source (datasourceutils) must use datasourceutils release connection before starting inner transactions let spring know connection has been returned. advantage of spring can have own additional transactionsynchronization logic. may use data source directly (without spring) , in case can call connection.close() return connections pool.
finally code of outer transaction (any transaction) should like:
public void dooutertransaction() throws throwable { defaulttransactiondefinition def = new defaulttransactiondefinition(); def.setname("mytx"); def.setpropagationbehavior(transactiondefinition.propagation_requires); transactionstatus status = txmanager.gettransaction(def); connection connection = null; cache cache = null; try { try { cache = ...; // cache cachemanager connection = datasourceutils.getconnection(mydatasource); // business logic } { datasourceutils.releaseconnection(connection, mydatasource); } doinnertransaction(); try { cache = ...; // cache cachemanager connection = datasourceutils.getconnection(mydatasource); // other business logic } { datasourceutils.releaseconnection(connection, mydatasource); } } catch (throwable ex) { txmanager.rollback(status); throw ex; } txmanager.commit(status); }
so not afraid of getting , releasing of db connection. have connections pool - fast. calling close() on connection returns pool (method name "release" better!). having active usertransaction not commit changes until call commit() explicitly.
thanks help!
Comments
Post a Comment