Giter Club home page Giter Club logo

btm's Introduction

Bitronix Transaction Manager (BTM)

Bitronix Transaction Manager (BTM) is a simple but complete implementation of the Java Transaction API (JTA) 1.1. This eXtended Architecture (XA) transaction manager provides all services required by the JTA while keeping the code as simple as possible for easier understanding of XA semantics.

The master version of the current source was built and published on the Maven Central repository.

Credits

BTM was created and maintained by the Bitronix team and its community, especially @bitronix and @BrettWooldridge.

Scalar, Inc., took over this great project so that we can continue to maintain and build on the project. We would like to thank @bitronix and @BrettWooldridge for their innovative work on BTM.

General information

For general information, see the following:

Configuration

For details about configuring BTM, see the following:

btm's People

Contributors

brettwooldridge avatar feeblefakie avatar josh-wong avatar komamitsu avatar lorban avatar marcus-nl avatar rankinc avatar recallwu avatar snicoll avatar sourcepond avatar yuppyavd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

btm's Issues

Intermittent unit test failure with Oracle JDK7

(I'm not sure how BTM even builds with JDK7, due to MockDriver and MockXADataSource not implementing getParentLogger(). However...)

I've run this several times with my changes to JdbcPooledConnection reverted (just to be sure), and there is an intermittent error in bitronix.tm.recovery.RecovererTest when built against JDK7. I have been unable to reproduce this when building against JDK5.

Running bitronix.tm.recovery.RecovererTest
Tests run: 9, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 6.838 sec <<< FAILURE!
testBackgroundRecovererSkippingInFlightTransactions(bitronix.tm.recovery.RecovererTest) Time elapsed: 0.838 sec <<< FAILURE!
junit.framework.AssertionFailedError: TX has been committed more or less times than just once expected:<1> but was:<2>
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.failNotEquals(Assert.java:283)
at junit.framework.Assert.assertEquals(Assert.java:64)
at junit.framework.Assert.assertEquals(Assert.java:195)
at bitronix.tm.recovery.RecovererTest.testBackgroundRecovererSkippingInFlightTransactions(RecovererTest.java:360)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)

Error show in tomcat logs

I see the following error suddenly from today in my tomcat logs and no messages are read from queue in my application, could anyone help me on this:
component.jms.DefaultJmsMessageListenerContainer Could not refresh JMS Connection for destination 'EmployeeQueue' - retrying using FixedBackOff{interval=5000, currentAttempts=1, maxAttempts=unlimited}. Cause: unable to get a connection from pool of a PoolingConnectionFactory with an XAPool of resource jms/ConnectionFactory with 10 connection(s) (0 still available)

LrcXAResource autocommit can't be restore

It happend to two transcations T1 & T2. T2's Propagation.REQUIRES_NEW, T1 is suspended. T2 submit and resume T1. T1 enlist to XAResourceManager, then xaResourceHolderState.start > LrcXAResource.start
LrcXAResource code line 152:
autocommitActiveBeforeStart = connection.getAutoCommit();
if (autocommitActiveBeforeStart) {
connection.setAutoCommit(false);
}

for now. autocommit have been set false before T1 been suspended, variable autocommitActiveBeforeStart is changed, it is not right flag. because when T1 submit , connection autocommit can't be restore before

I used btm2.1.4

Unable to get a connection pool of a PoolingDataSource

We are occasionally encountering a problem where we can't get a connection from the pool after the network connection was dropped and recovered.
java.sql.SQLException: unable to get a connection from pool of a PoolingDataSource containing an XAPool of resource feebase with 0 connection(s) (0 still available)
at bitronix.tm.resource.jdbc.PoolingDataSource.getConnection(PoolingDataSource.java:262)
...
Caused by: java.sql.SQLException: unable to connect to non-XA resource oracle.jdbc.OracleDriver
....
Caused by: java.sql.SQLRecoverableException: IO Error: Connection reset
....
Caused by: java.net.SocketException: Connection reset

What can we do to 'reboot' PoolingDataSource, or is there a configuration we should set to get it to auto-recover?

We are using btm 2.1.1, and I have found a similar problem reported for btm 2.1.4 on StackOverflow similar problem reported for 2.1.4 so I'm not confident that upgrading versions will fix the problem.
We are running on a linux server, and we're using Spring 3.1.2.

MaxIdleTime vs. MinPoolSize in XAPool

According to the wiki, the pool size should not drop below the minimum pool size when the maximum idle time has been reached. Unfortunately, this is not the case. In our system we had a minimum pool size of 300. 297 were idle and only 3 were in use. This results in closing 297 idle connections within the PoolShrinkingTask and re-open them again within the same method: XAPool#expireOrCloseStatefulHolders

Add more documentation

Hi, firstly thank you for such a great little transaction manager. I have used it many times. However since Codehaus was shutdown, the documentation that exists here is not as good as it was (e.g. http://docs.codehaus.org/display/BTM/Tomcat). Specifically, there is no information on how to integrate BTM with Tomcat and Jetty.

If need by, I would be happy to help by creating a pull request, but I'd need the original documentation to start with.

Thanks,
Ant

PS What I can find:

http://bitronix-transaction-manager.10986.n7.nabble.com/Bitronix-on-Ubuntu-server-V12-w-Tomcat7-issue-td1612.html

http://documentation.bonitasoft.com/ubuntu-openjdk-tomcat-mysql

http://bitronix-transaction-manager.10986.n7.nabble.com/tomcat-7-0-26-and-bitronix-td1155.html

Test failures occur when building with Java 8

For example:

Tests run: 3, Failures: 0, Errors: 3, Skipped: 0, Time elapsed: 0.508 sec <<< FAILURE!
testAcquiringConnectionAfterRecoveryDoesNotMarkAsFailed(bitronix.tm.JdbcFailedPoolTest)  Time elapsed: 0.504 sec  <<< ERROR!
java.lang.ExceptionInInitializerError
    at bitronix.tm.resource.jdbc.JdbcPooledConnection.getConnectionHandle(JdbcPooledConnection.java:433)
    at bitronix.tm.resource.jdbc.JdbcPooledConnection.getConnectionHandle(JdbcPooledConnection.java:312)
    at bitronix.tm.resource.common.XAPool.getConnectionHandle(XAPool.java:189)
    at bitronix.tm.resource.jdbc.PoolingDataSource.startRecovery(PoolingDataSource.java:336)
    at bitronix.tm.recovery.IncrementalRecoverer.recover(IncrementalRecoverer.java:54)
    at bitronix.tm.JdbcFailedPoolTest.testAcquiringConnectionAfterRecoveryDoesNotMarkAsFailed(JdbcFailedPoolTest.java:56)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at junit.framework.TestCase.runTest(TestCase.java:168)
    at junit.framework.TestCase.runBare(TestCase.java:134)
    at junit.framework.TestResult$1.protect(TestResult.java:110)
    at junit.framework.TestResult.runProtected(TestResult.java:128)
    at junit.framework.TestResult.run(TestResult.java:113)
    at junit.framework.TestCase.run(TestCase.java:124)
    at junit.framework.TestSuite.runTest(TestSuite.java:243)
    at junit.framework.TestSuite.run(TestSuite.java:238)
    at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: bitronix.tm.internal.BitronixRuntimeException: error initializing JdbcProxyFactory
    at bitronix.tm.resource.jdbc.proxy.JdbcProxyFactory$Initializer.initialize(JdbcProxyFactory.java:82)
    at bitronix.tm.resource.jdbc.proxy.JdbcProxyFactory$Initializer.access$000(JdbcProxyFactory.java:60)
    at bitronix.tm.resource.jdbc.proxy.JdbcProxyFactory.<clinit>(JdbcProxyFactory.java:39)
    ... 31 more
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.io.IOException: invalid constant type: 18
    at bitronix.tm.resource.jdbc.proxy.JdbcJavassistProxyFactory.createProxyCallableStatementClass(JdbcJavassistProxyFactory.java:183)
    at bitronix.tm.resource.jdbc.proxy.JdbcJavassistProxyFactory.<init>(JdbcJavassistProxyFactory.java:74)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at java.lang.Class.newInstance(Class.java:438)
    at bitronix.tm.resource.jdbc.proxy.JdbcProxyFactory$Initializer.initialize(JdbcProxyFactory.java:80)
    ... 33 more
Caused by: java.lang.RuntimeException: java.io.IOException: invalid constant type: 18
    at javassist.CtClassType.getClassFile2(CtClassType.java:203)
    at javassist.CtClassType.subtypeOf(CtClassType.java:303)
    at javassist.CtClassType.subtypeOf(CtClassType.java:318)
    at javassist.CtClassType.subtypeOf(CtClassType.java:318)
    at javassist.compiler.MemberResolver.compareSignature(MemberResolver.java:247)
    at javassist.compiler.MemberResolver.lookupMethod(MemberResolver.java:119)
    at javassist.compiler.MemberResolver.lookupMethod(MemberResolver.java:96)
    at javassist.compiler.TypeChecker.atMethodCallCore(TypeChecker.java:704)
    at javassist.compiler.TypeChecker.atCallExpr(TypeChecker.java:681)
    at javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:156)
    at javassist.compiler.ast.CallExpr.accept(CallExpr.java:45)
    at javassist.compiler.CodeGen.doTypeCheck(CodeGen.java:241)
    at javassist.compiler.CodeGen.compileExpr(CodeGen.java:228)
    at javassist.compiler.CodeGen.atReturnStmnt2(CodeGen.java:597)
    at javassist.compiler.JvstCodeGen.atReturnStmnt(JvstCodeGen.java:424)
    at javassist.compiler.CodeGen.atStmnt(CodeGen.java:362)
    at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
    at javassist.compiler.CodeGen.atStmnt(CodeGen.java:350)
    at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
    at javassist.compiler.CodeGen.atMethodBody(CodeGen.java:291)
    at javassist.compiler.Javac.compileBody(Javac.java:222)
    at javassist.CtBehavior.setBody(CtBehavior.java:401)
    at javassist.CtBehavior.setBody(CtBehavior.java:375)
    at bitronix.tm.resource.jdbc.proxy.JdbcJavassistProxyFactory.generateProxyClass(JdbcJavassistProxyFactory.java:260)
    at bitronix.tm.resource.jdbc.proxy.JdbcJavassistProxyFactory.createProxyCallableStatementClass(JdbcJavassistProxyFactory.java:180)
    ... 40 more
Caused by: java.io.IOException: invalid constant type: 18
    at javassist.bytecode.ConstPool.readOne(ConstPool.java:1090)
    at javassist.bytecode.ConstPool.read(ConstPool.java:1033)
    at javassist.bytecode.ConstPool.<init>(ConstPool.java:149)
    at javassist.bytecode.ClassFile.read(ClassFile.java:737)
    at javassist.bytecode.ClassFile.<init>(ClassFile.java:108)
    at javassist.CtClassType.getClassFile2(CtClassType.java:190)
    ... 64 more

What minimum jdk of BTM?

What minimum jdk of BTM?
I cannot maven compile on jdk1.5. some source refer to jdk1.6.

Thank you.
Nicky

Getting this error suddenly in one of tomcat instance

I am not sure what caused below issue. I have two tomcat instances with the same configuration. but I am only seeing below issue in one of the instance.

org.springframework.transaction.CannotCreateTransactionException: JTA failure on begin; nested exception is bitronix.tm.internal.BitronixSystemException: error logging status
at org.springframework.transaction.jta.JtaTransactionManager.doBegin(JtaTransactionManager.java:845)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:427)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy331.processPayment(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:870)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:120)
at org.springframework.boot.context.web.ErrorPageFilter.access$000(ErrorPageFilter.java:61)
at org.springframework.boot.context.web.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:95)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:113)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:724)
Caused by: bitronix.tm.internal.BitronixSystemException: error logging status
at bitronix.tm.BitronixTransaction.setStatus(BitronixTransaction.java:400)
at bitronix.tm.BitronixTransaction.setStatus(BitronixTransaction.java:379)
at bitronix.tm.BitronixTransaction.setActive(BitronixTransaction.java:367)
at bitronix.tm.BitronixTransactionManager.begin(BitronixTransactionManager.java:126)
at org.springframework.transaction.jta.JtaTransactionManager.doJtaBegin(JtaTransactionManager.java:875)
at org.springframework.transaction.jta.JtaTransactionManager.doBegin(JtaTransactionManager.java:832)
... 70 more
Caused by: bitronix.tm.journal.CorruptedTransactionLogException: corrupted log found at position 1246411 (no record terminator found)
at bitronix.tm.journal.TransactionLogCursor.readLog(TransactionLogCursor.java:102)
at bitronix.tm.journal.TransactionLogCursor.readLog(TransactionLogCursor.java:67)
at bitronix.tm.journal.DiskJournal.collectDanglingRecords(DiskJournal.java:363)
at bitronix.tm.journal.DiskJournal.copyDanglingRecords(DiskJournal.java:337)
at bitronix.tm.journal.DiskJournal.swapJournalFiles(DiskJournal.java:300)
at bitronix.tm.journal.DiskJournal.log(DiskJournal.java:101)
at bitronix.tm.BitronixTransaction.setStatus(BitronixTransaction.java:389)

How to bind the unWrapped native connection object to Spring @Transactional platformTransactionManager

Tomcat 8 Web server with Bitronix Transaction Manager as Distributed Transaction Manager
Below are the properties for datasource :
resource.ds1.className=oracle.jdbc.xa.client.OracleXADataSource
resource.ds1.uniqueName=jdbc/oracledb
resource.ds1.minPoolSize=0
resource.ds1.maxPoolSize=10
resource.ds1.driverProperties.user=user1
resource.ds1.driverProperties.password=user2
resource.ds1.driverProperties.URL=jdbc:oracle:thin:@//URL:1521/SCHEMA
resource.ds1.allowLocalTransactions=true
resource.ds1.shareTransactionConnections=false
resource.ds1.localAutoCommit=true
resource.ds1.ignoreRecoveryFailures=false
resource.ds1.automaticEnlistingEnabled=true
resource.ds1.applyTransactionTimeout=true

Below is the bean configuration for datasource in Spring:
@bean(name = "dataSource", initMethod = "init", destroyMethod = "close")
public DataSource dataSource() throws Exception {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource ds = dataSourceLookup.getDataSource("java:comp/env/jdbc/oracledb");
return ds;
}
@bean(name = "bitronixTransactionManager", destroyMethod = "shutdown")
public UserTransaction bitronixTransactionManager() throws NamingException {
JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
return (UserTransaction) jndiObjectFactoryBean.getJndiTemplate().lookup("java:comp/UserTransaction");
}

@Bean(name = "platformTransactionManager")
@DependsOn({ "bitronixTransactionManager" })
public PlatformTransactionManager platformTransactionManager() throws Throwable {
	JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(bitronixTransactionManager());
	jtaTransactionManager.setRollbackOnCommitFailure(true);
	jtaTransactionManager.setAllowCustomIsolationLevels(true);
	jtaTransactionManager.setGlobalRollbackOnParticipationFailure(true);
	return jtaTransactionManager;
}

Below is my method in one of the classes
publi class Test{

@Autowired
DataSource dataSource;
@transactional(value = "platformTransactionManager", propagation = Propagation.REQUIRED)
public void testTransaction() {
throws Exception {
Connection conn = DataSourceUtils.getConnection(dataSource);
Connection connectionToUse = conn.unwrap(java.sql.Connection.class);
//1. create a statement using connectionToUse and write a record to the database
//2. have some JMS related operations to publish which I dont have issue to publish. everything works fine
throw new RuntimeException();
//3. after throwing an exception the write operation performed by connectinToUse object should be rolled back but in this case, it's not getting rolled back,
}
}

not able to bind the unwrapped connection object to the existing transaction.

Need an empty properties file to reference in my Jetty module

I would appreciate if someone in the core team can create an empty btm-config.properties file associated with the btm project for use in creating a Jetty 9 modules file.
I had to reach into the zyeeda/docker github project to get a blank properties file but it would be nice if I don;t have to leave the BTM project for this.

#
# Jetty BTM Module
#   Bitronix Transaction Manager
#
[name]
btm

[depend]
jndi
resources

[lib]
lib/btm/*.jar

[xml]
etc/jetty-btm.xml

[files]
etc/
resources/
work/
ext/btm/
maven://javax.transaction/jta/1.1|lib/btm/jta-1.5.jar
maven://org.codehaus.btm/btm/2.1.4|lib/btm/btm-2.1.4.jar
maven://org.javassist/javassist/3.21.0-GA|lib/btm/javassist-3.21.0-GA.jar
https://raw.githubusercontent.com/zyeeda/docker/master/java/jetty9/jetty_base/resources/bitronix-default-config.properties|resources/btm-config.properties

Thank you.

BTM does not shrink its connection pool aggressively enough

We have configured our connection pools to have a "max idle time" of 600 seconds and a minimum size of 5. However, although we see the pools grow readily enough during period of high usage, their number of connections is a lot slower to decrease again afterwards.

This appears to be due to XAPool.availablePool being implemented as a FIFO - we are still able to iterate over the entire pool within 10 minutes, even if the pool is overpopulated. I think that XAPool.availablePool needs to be implemented as a LIFO instead. This would ensure that connections only remain in use if the application truly requires that many connections simultaneously.

(The patch for this seems trivial enough - using a BlockingDeque instead of a BlockingQueue, and then adding connections to the front rather than the back. However, it would be "nice" if my "generics" patch were pulled first.... ;-).)

How to release abandoned connections?

Hi

How configure pool to release all idle and abandoned connections?

The maxIdleTime and PoolShrinkingTask cleans only availablePool but already obtained idle or abandoned connections are in accessiblePool i inaccessiblePool and these pools are not cleaned.
This situation can occur in code without connection.close.
It seems to me that classic pools like TomcatDbcp or Jboss pools can handle this situation.
For example Apache Commons use such concept as AbandonedTrace, RemoveAbandonedOnMaintenance
and org.apache.commons.pool2.impl.GenericObjectPool.removeAbandoned

/**
* Recover abandoned objects which have been checked out but
* not used since longer than the removeAbandonedTimeout.
*
* @param ac The configuration to use to identify abandoned objects
*/
private void removeAbandoned(AbandonedConfig ac)

Of course it has a little impact on performance but server restart is not required if problem exist and can be gracefully logged..

Connection in bad state

I'm not certain that this is a Bitronix issue; but we've had the following condition occur in our production system.

The problem seems to stem from an issue during either commit or rollback of an Lrc resource. I am not certain whether the fact that it is in Lrc mode is related - since this particular resource is always in that mode. I do not suspect that it is related to Lrc.

Here is a sample stack:

bitronix.tm.internal.BitronixXAException: error preparing non-XA resource
    at bitronix.tm.resource.jdbc.lrc.LrcXAResource.prepare(LrcXAResource.java:229)
    at bitronix.tm.twopc.Preparer$PrepareJob.execute(Preparer.java:157)
    at bitronix.tm.twopc.executor.Job.run(Job.java:68)
    at bitronix.tm.twopc.executor.SyncExecutor.submit(SyncExecutor.java:27)
    at bitronix.tm.twopc.AbstractPhaseEngine.runJobsForPosition(AbstractPhaseEngine.java:120)
    at bitronix.tm.twopc.AbstractPhaseEngine.executePhase(AbstractPhaseEngine.java:84)
    at bitronix.tm.twopc.Preparer.prepare(Preparer.java:88)
    at bitronix.tm.BitronixTransaction.commit(BitronixTransaction.java:281)
    at com.gtnexus.server.mdb.StandardMessageService.run(StandardMessageService.java:202)
    at com.google.common.util.concurrent.AbstractExecutionThreadService$1$2.run(AbstractExecutionThreadService.java:60)
    at com.google.common.util.concurrent.Callables$3.run(Callables.java:93)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.sql.SQLNonTransientConnectionException: [GTN][SQLServer JDBC Driver]Connection reset by peer: socket write error
    at com.gtnexus.jdbc.sqlserverbase.ddcw.b(Unknown Source)
    at com.gtnexus.jdbc.sqlserverbase.ddcw.a(Unknown Source)
    at com.gtnexus.jdbc.sqlserverbase.ddcv.b(Unknown Source)
    at com.gtnexus.jdbc.sqlserverbase.ddcv.a(Unknown Source)
    at com.gtnexus.jdbc.sqlserverbase.ddcv.a(Unknown Source)
    at com.gtnexus.jdbc.sqlserver.tds.ddg.a(Unknown Source)
    at com.gtnexus.jdbc.sqlserver.SQLServerImplConnection.a(Unknown Source)
    at com.gtnexus.jdbc.sqlserver.SQLServerImplConnection.j(Unknown Source)
    at com.gtnexus.jdbc.sqlserverbase.BaseConnection.commit(Unknown Source)
    at bitronix.tm.resource.jdbc.lrc.LrcXAResource.prepare(LrcXAResource.java:225)

After this occurs, the connection/datasource remains associated with this original transaction; but is made available again in the pool. On the next use, that connection will fail the subsequent transaction, complaining that; "resource already started on XID a Bitronix XID". Effectively saying that it cannot participate in a new transaction, because it is already associated with the original one.

i'd like to be able to mark the referenced connection as bad when it encounters the first problem - and ideally remove it from the pool - to make room for a replacement. I am comfortable making changes in the core Bitronix code, but could use an assist in finding the best way to accomplish this -- or any other ideas about how to prevent this problem from occurring.

From everything we can tell, the original issue (which happens very infrequently) does not have an addressable root cause.

Many thanks for any assistance!

Release of 3.0.0

Are there any plans to release 3.0.0 version as 2.1.x does not work with hibernate 4.2 and above.

Why do resource recovery in ResourceRegistrar.register?

Simple (potentially dumb) question: why does the ResourceRegistrar.register() method attempt resource recovery if the transaction manager is already running?

The reason I ask is the following:
Our application fails to startup because of a single transaction causing a RecoveryException. This exception is raised when we try to register a resource with the transaction manager. At that point the transaction manager is already running because it was started using the Tomcat BTMLifecycleListener, and consequently ResourceRegistrar.register() attempts recovery:

Caused by: bitronix.tm.recovery.RecoveryException: error recovering resource '1460720339996_3D_DOCCLE' due to an incompatible heuristic decision at bitronix.tm.recovery.IncrementalRecoverer.recover(IncrementalRecoverer.java:94) ~[btm-2.1.2.jar:2.1.2] at bitronix.tm.resource.ResourceRegistrar.register(ResourceRegistrar.java:78) ~[btm-2.1.2.jar:2.1.2] at grid.storage.transaction.btm.PoolingSessionFactory.buildXAPool(PoolingSessionFactory.java:68) ~[honeycomb-bitronix-1.8.23.jar:na] at grid.storage.transaction.btm.PoolingSessionFactory.init(PoolingSessionFactory.java:52) ~[honeycomb-bitronix-1.8.23.jar:na] ... 42 common frames omitted

So because of this the application cannot register the resource with the transaction manager and of course needs to fail. It seems a bit harsh to prevent full application startup just because of a recovery failure on a single transaction.
Is there a better way to handle this kind of issue?

XAPool: error closing a JdbcPooledConnection ... in state CLOSED

I am receiving a warning that a closed connection couldn't be closed. The connection shows "usage count 0". Is that something I should be worried about (below is the stack trace)?

Although the stacktrace shows "Cannot close a connection while a transaction is still active" I don't receive a transaction timeout error!? Why would XAPool trying to close a connection that is still in use and on the other hand why does the transaction manager not output an error for a transaction timeout (there is no transaction timeout in the logs)?

Technical:

  • Apache Derby 10.10.2.0
  • Bitronix 3.0.0 (latest build from github)

Stacktrace:

bitronix.tm.resource.common.XAPool: error closing a JdbcPooledConnection from datasource btm-ds-0x00000001-0x0001-21 in state CLOSED with usage count 0 wrapping org.apache.derby.client.ClientXAConnection40@2571fff7
java.sql.SQLException: Cannot close a connection while a transaction is still active.
org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
org.apache.derby.client.am.Connection.closeResourcesX(Unknown Source)
org.apache.derby.client.am.Connection.closeResources(Unknown Source)
org.apache.derby.client.net.NetConnection.closeResources(Unknown Source)
org.apache.derby.client.ClientPooledConnection.close(Unknown Source)
org.apache.derby.client.ClientXAConnection.close(Unknown Source)
bitronix.tm.resource.jdbc.JdbcPooledConnection.close(JdbcPooledConnection.java:158)
bitronix.tm.resource.common.XAPool.expireStatefulHolder(XAPool.java:538)
bitronix.tm.resource.common.XAPool.getInPool(XAPool.java:322)
bitronix.tm.resource.common.XAPool.getConnectionHandle(XAPool.java:181)
bitronix.tm.resource.jdbc.PoolingDataSource.startRecovery(PoolingDataSource.java:336)
bitronix.tm.recovery.Recoverer.recover(Recoverer.java:265)
bitronix.tm.recovery.Recoverer.recoverAllResources(Recoverer.java:233)
bitronix.tm.recovery.Recoverer.run(Recoverer.java:144)
java.lang.Thread.run(Unknown Source)
Caused by: org.apache.derby.client.am.SqlException: Cannot close a connection while a transaction is still active.
org.apache.derby.client.am.Connection.checkForTransactionInProgress(Unknown Source)
org.apache.derby.client.am.Connection.closeResourcesX(Unknown Source)
org.apache.derby.client.am.Connection.closeResources(Unknown Source)
org.apache.derby.client.net.NetConnection.closeResources(Unknown Source)
org.apache.derby.client.ClientPooledConnection.close(Unknown Source)
org.apache.derby.client.ClientXAConnection.close(Unknown Source)
bitronix.tm.resource.jdbc.JdbcPooledConnection.close(JdbcPooledConnection.java:158)
bitronix.tm.resource.common.XAPool.expireStatefulHolder(XAPool.java:538)
bitronix.tm.resource.common.XAPool.getInPool(XAPool.java:322)
bitronix.tm.resource.common.XAPool.getConnectionHandle(XAPool.java:181)
bitronix.tm.resource.jdbc.PoolingDataSource.startRecovery(PoolingDataSource.java:336)
bitronix.tm.recovery.Recoverer.recover(Recoverer.java:265)
bitronix.tm.recovery.Recoverer.recoverAllResources(Recoverer.java:233)
bitronix.tm.recovery.Recoverer.run(Recoverer.java:144)
java.lang.Thread.run(Unknown Source)

Clarify requirements for XAResourceProducer unique name

Each XAResourceProducer needs to have a unique name that is used by the ResourceRegistrar to keep track of the resource. The JavaDoc of XAResourceProducer simply says:

Get the resource name as registered in the transactions journal.

The JavaDoc of ResourceBean additionally states:

Specify the resource unique name to be used to identify this resource during recovery. This name will be registered in the transactions journal so once assigned it must never be changed.

What exactly does this mean?

  • How unique does the name need to be? Does it only need to be unique per ResourceRegistrar? Or unique across the whole system, for instance when running in a cluster?
  • What does "must never be changed" mean? No changes while the transaction manager is up-and-running? Or no changes ever? For instance, image a resource is named X the first time an application starts up. Is it okay for that same resource to be named Y after a later restart of the application where of course the transaction manager is using the same journal files?

Closing a connection with "usageCount > 1" is possible.

JdbcPooledConnection.close() says:

    // this should never happen, should we throw an exception or log at warn/error?
    if (usageCount > 0) {
        log.warn("close connection with usage count > 0, " + this);
    }

However, should JdbcPooledConnection.getConnectionHandle() throw a SQLException because (e.g.) testConnection() has failed, then usageCount will still have been incremented when XAPool.getConnectionHandle() tries to close the invalid connection.

The patch is trivial:

// Increment the usage count
usageCount++
try {

   // etc

} catch (SQLException e) {
    // This connection must be invalid, so revert the usage counter.
    // Note: Closing a handle with usageCount > 0 "should never happen".
    --usageCount;
    throw e;
}

Cheers,
Chris

LruStatementCache is broken.

The following test fails:

PreparedStatement stmt = c.prepareStatement(DB_SELECT_SYSDATE_SQL);
assertFalse(stmt.isClosed());
stmt.close();
assertTrue(stmt.isClosed());

stmt = c.prepareStatement(DB_SELECT_SYSDATE_SQL);
assertFalse(stmt.isClosed());

The problem is that the proxies inside the LruStatementCache are never replaced, which means that once "pretendClosed = true", it remains true until the statement is evicted from the cache.

Bitronix and Database clustering

I have the below configuration:
Tomcat 8.0.30 as application server
BTM:2.1.4
SQL Server 2014 Cluster setup with two Nodes

Does BTM supports database clustering with the above version. If yes, then is there any documentation available for the same.
The specific scenario being N1 and N2 are two nodes in the cluster and N1 goes down during transaction, in this case how can we ensure that the application is in consitent state.
We also need to do Oracle RAC support with the BTM hence any pointers to the same is highly appriciated

Connection pool unable to recover after database connectivity loss

We are using Bitronix 2.1.4 with MySQL connector 5.1.39 and Spring Data JPA 1.11.4.RELEASE. Once in a while the app server loses network connectivity to the database server. Once this happens, all connections in the Bitronix pool quickly run into errors. However, they continue to throw errors even after the network connectivity is restored. The following stacktrace appears in the logs:

Caused by: java.sql.SQLException: error enlisting a JdbcConnectionHandle of a JdbcPooledConnection from datasource dataSource in state ACCESSIBLE with usage count 1 wrapping com.mysql.jdbc.jdbc2.optional.JDBC4SuspendableXAConnection@65e0ae83 on com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@6d4e71b1
    at bitronix.tm.resource.jdbc.JdbcConnectionHandle.enlistResource(JdbcConnectionHandle.java:87)
    at bitronix.tm.resource.jdbc.JdbcConnectionHandle.prepareStatement(JdbcConnectionHandle.java:242)
    at sun.reflect.GeneratedMethodAccessor178.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at bitronix.tm.resource.jdbc.BaseProxyHandlerClass.invoke(BaseProxyHandlerClass.java:64)
    at com.sun.proxy.$Proxy32.prepareStatement(Unknown Source)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172)
    ... 133 common frames omitted
Caused by: bitronix.tm.internal.BitronixSystemException: cannot enlist an XAResourceHolderState with uniqueName=dataSource XAResource=com.mysql.jdbc.jdbc2.optional.JDBC4SuspendableXAConnection@65e0ae83 with XID a Bitronix XID [626974726F6E69782D3230313730373234303332303339000000000EA9F59A00001FCC : 626974726F6E69782D3230313730373234303332303339000000000EA9F59C00001FCD], error=XAER_RMFAIL
    at bitronix.tm.BitronixTransaction.enlistResource(BitronixTransaction.java:139)
    at bitronix.tm.resource.common.TransactionContextHelper.enlistInCurrentTransaction(TransactionContextHelper.java:69)
    at bitronix.tm.resource.jdbc.JdbcConnectionHandle.enlistResource(JdbcConnectionHandle.java:85)
    ... 141 common frames omitted
Caused by: com.mysql.jdbc.jdbc2.optional.MysqlXAException: XAER_RMFAIL: The command cannot be executed when global transaction is in the  ROLLBACK ONLY state
    at com.mysql.jdbc.jdbc2.optional.MysqlXAConnection.mapXAExceptionFromSQLException(MysqlXAConnection.java:581)
    at com.mysql.jdbc.jdbc2.optional.MysqlXAConnection.dispatchCommand(MysqlXAConnection.java:566)
    at com.mysql.jdbc.jdbc2.optional.MysqlXAConnection.start(MysqlXAConnection.java:507)
    at com.mysql.jdbc.jdbc2.optional.SuspendableXAConnection.start(SuspendableXAConnection.java:172)
    at bitronix.tm.internal.XAResourceHolderState.start(XAResourceHolderState.java:220)
    at bitronix.tm.internal.XAResourceManager.enlist(XAResourceManager.java:111)
    at bitronix.tm.BitronixTransaction.enlistResource(BitronixTransaction.java:130)
    ... 143 common frames omitted
Caused by: java.sql.SQLException: XAER_RMFAIL: The command cannot be executed when global transaction is in the  ROLLBACK ONLY state
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:963)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3966)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3902)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2526)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2673)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2545)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2503)
    at com.mysql.jdbc.StatementImpl.executeInternal(StatementImpl.java:839)
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:739)
    at com.mysql.jdbc.jdbc2.optional.MysqlXAConnection.dispatchCommand(MysqlXAConnection.java:560)

The JDBC URL is jdbc:mysql://db.domain.com:3306/domain?pinGlobalTxToPhysicalConnection=true. The data source class name is com.mysql.jdbc.jdbc2.optional.MysqlXADataSource.

bitronix.tm.osgi.Activator class is incompatible with JDK5

The Activator class contains these lines:

FileReader fileReader = new FileReader(cfgFile);
try {
    btmProperties.load(fileReader);
}
finally {
    fileReader.close();
}

Unfortunately, the Properties.load(Reader) API only exists since JDK6. To be compatible with JDK5 (which is your declared target), you need to use a FileInputStream instead of a FileReader.

Or you could switch to JDK6, now that JDK8 has been released.

On the positive side, this does appear to be the only JDK6 issue in the project.

PropertyUtils.setProperty() fails for objects that clone their properties.

In bitronix.tm.utils.PropertyUtilsTest, I modified the Destination class to protect its Properties object:

public static class Destination {
    private Properties props;
    ...

    public Properties getProps() {
        return (props == null) ? null : (Properties) props.clone();
    }

    public void setProps(Properties props) {
        this.props = (props == null) ? null : (Properties) props.clone();
    }

This breaks the test, because Destination.props is now a clone of an empty Properties object that never receives the intended property value.

The relevance of this issue is that OracleXADataSource.getConnectionProperties() and OracleXADataSource.setConnectionProperties() also clone the Properties object. Hence a line in resources.properties such as:

resource.ds1.driverProperties.connectionProperties.oracle.jdbc.TcpNoDelay=true

always does nothing.

searching best solution for error handling

after reading a message from Active MQ My transaction starts
What transaction? If you're speaking about a JTA transaction that encompasses your JMS and JDBC resources, it has to be started before you read the JMS message.
...while doing second database transaction...

Recovery thread connection acquiring enhancement

In our current enterprise system we've been struggling to lower the poolingDataSource.acquisitionTimeout from the default 30s to some more appropriate value (1-5s).

For "classic" DataSource.getConnection() scenarios it was possible, thanks to using FlexyPool BTM support.

The only problem is the recovery thread, since we cannot intercept the time-out exceptions and there is no default retrying mechanisms or the possibility for using a separate connection from the regular pooled connections.

So we get:

bitronix.tm.recovery.RecoveryException: cannot start recovery on a PoolingDataSource containing an XAPool of resource dtfDataSource with 7 connection(s) (0 still available)
at bitronix.tm.resource.jdbc.PoolingDataSource.startRecovery(PoolingDataSource.java:288) ~[btm-2.1.3.jar:2.1.3]
at bitronix.tm.recovery.Recoverer.recover(Recoverer.java:258) [btm-2.1.3.jar:2.1.3]
at bitronix.tm.recovery.Recoverer.recoverAllResources(Recoverer.java:226) [btm-2.1.3.jar:2.1.3]
at bitronix.tm.recovery.Recoverer.run(Recoverer.java:142) [btm-2.1.3.jar:2.1.3]
at java.lang.Thread.run(Thread.java:662) [na:1.6.0_45]
Caused by: bitronix.tm.internal.BitronixRuntimeException: XA pool of resource dtfDataSource still empty after 1s wait time
at bitronix.tm.resource.common.XAPool.waitForConnectionInPool(XAPool.java:423) ~[btm-2.1.3.jar:2.1.3]
at bitronix.tm.resource.common.XAPool.getInPool(XAPool.java:374) ~[btm-2.1.3.jar:2.1.3]
at bitronix.tm.resource.common.XAPool.getConnectionHandle(XAPool.java:123) ~[btm-2.1.3.jar:2.1.3]
at bitronix.tm.resource.jdbc.PoolingDataSource.startRecovery(PoolingDataSource.java:284) ~[btm-2.1.3.jar:2.1.3]
... 4 common frames omitted

What do you think of having some fail-over options such as:

  1. Add a Bitronix configuration so that the recovery connection acquire will attempt N times before giving up.
  2. Add a Bitronix configuration so that the recovery can use a dedicated JDBC connection that's never served trough DataSource.getConnection().

Q

native connection from PoolingDataSource of Bitronix

Connection already closed on first try only

I am working with an open source application. Our team has switched to bitronix. I am seeing a weird bug, where the connection is already closed.

Exception message is [connection handle already closed]

  • Vendor error code [0]
  • SQL state code [null]
  • The root stack trace is -->
    java.sql.SQLException: connection handle already closed
    at bitronix.tm.resource.jdbc.JdbcConnectionHandle.enlistResource(JdbcConnectionHandle.java:81)
    at bitronix.tm.resource.jdbc.JdbcConnectionHandle.prepareStatement(JdbcConnectionHandle.java:288)

This happens when returning to a document after doing a 'lookup' search. When returning to the document, the application will do a pessimistic lock check which queries the database for this check.

The weird thing is, this only occurs the very first time a user logs in. After getting this exception if the user tries again, it will always work. Any help is greatly appreciated!

I'll attach the complete stack trace as a file. Not sure if this is a bitronix bug or something else. I was advised to open an issue here. Any help is appreciated!

Is PreparedStatementJavaProxy.close() correct?

I've been examining PreparedStatementJavaProxy, and I am curious about the close() function. When the statement cache is enabled, the close() function executes these lines:

// Return to cache so the usage count can be updated
jdbcPooledConnection.putCachedStatement(cacheKey, delegate);

However, all other usages of putCachedStatement() look like:

PreparedStatement stmt = delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
cachedStmt = JdbcProxyFactory.INSTANCE.getProxyPreparedStatement(jdbcPooledConnection, stmt, cacheKey);
jdbcPooledConnection.putCachedStatement(cacheKey, cachedStmt);

In other words, the statements cache seems to expect to contain JavaProxy objects rather than native PreparedStatement objects. In which case, shouldn't PreparedStatementJavaProxy.close() do this instead?

// Return to cache so the usage count can be updated
jdbcPooledConnection.putCachedStatement(cacheKey, getProxy());

This matters, because I believe that the LruEvictionListener needs to unwrap the PreparedStatement in order to extract (and hence close) the native PreparedStatement, and so avoid a memory leak. But this means that I need to be sure that it is unwrapping a PreparedStatementJavaProxy in the first place.

Thoughts, anyone?
Cheers,
Chris

Question: Tomcat isn't reading the conf/resources.properties file.

Hello,
I am new at using this artifact. I am trying to configure the application with BTM. Followed the documentation and yet, unable to get a successful startup of the application. Below is the message that I see in the start up log because of which the application appears to be failing to acquire the database connection.

WARNING: Failed to register in JMX: javax.naming.NamingException: no resource registered with uniqueName 'jdbc/jbpm', available resources: []

Please advice how to address this issue. Let me know if any additional information is needed to help.

Thanks

Commit Markable Resource with Bitronix?

Hi,

I'm using Bitronix with an LRC resource, and I have the following issue, which I believe is an instance of a known failure case with the LRC technique: Commit is called on the transaction, and the non-XA resource takes a while (~30 seconds) to complete the commit. During this window the system shuts down. After system restart the recoverer doesn't commit the XA resource (because it didn't register the non-XA commit completing). As a result, the non-XA resource is committed and the XA resource is not.

Any advice on how to get around this failure case? I can't do much about the long commit time for the non-XA resource. One technique I believe would solve the problem is the Commit Markable Resource technique described here. Is that supported by Bitronix, and if not, how hard would it be to extend Bitronix to do it (I'd consider contributing if it's feasible)? Any pointers would be greatly appreciated.

Thanks!

Christian

Statistics enhancements: maxWaitTime and numberOfConnections averages

I feel we could all benefit from having more detailed statistics, especially if exported through JMX as well. In my current production set-up we have tens of apps (web nodes, import apps, schedulers, each one with a BTM connection pool), all of them concurring for the limited set of database connections.

Trying to set the min and max pool size is more like a wild guess, and I think we can improve this process. For start, we could add more statistics info and make them available through JMX.

  1. We could add:
  • the cummulativeWaitTime (the time spent in XAPool.getInPool().waitForConnectionInPool())
  • the cummulativeConnectionRequestNumber (how many requests have been recorded)

Dividing these two could get us the average wait time.

  1. We could also have:
  • averageInPoolSize

Currently we have the instant in-pool size info, which is useful, but it changes so rapidly that it makes very difficult to poll it's value and make sure you really calculated a true average. If we set the min and max pool size, we are also interested in the average in-pool size (is it closer to min or to max), so we could better reason on the current pool size settings.

Question on rollback

I am not sure if it's possible, Is there any way in bitronix distributed transaction for one Specific exception I can commit JMS Transaction alone and roll back the DB transaction.

Support custom XAResourceProducer implementations in ResourceLoader

The ResourceLoader is hard-coded to support two types of XAResourceProducer implementations: the PoolingDataSource for a JDBC XADataSource and the PoolingConnectionFactory for a JMX XAConnectionFactory.

We have our own custom XAResourceProducer implementations and currently we need to manually register them with the transaction manager (ResourceRegistrar). This is inconvenient.

I would like to request the ResourceLoader be enhanced to support custom XAResourceProducer implementations. Maybe it can recognize a "resource.name.producerClassName" property in the properties file and if (optionally) specified use that?

ConcurrentModificationException in LRU statement cache on close connection

Found during testing of application with PostgreSQL...

22:02:58,104 [XAPool ] [bitronix-task-scheduler ] WARN - error closing a JdbcPooledConnection from datasource ziptie-ds in state CLOSED with usage count 0 wrapping org.postgresql.xa.PGXAConnection@47ea7f02
java.util.ConcurrentModificationException
at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:394)
at java.util.LinkedHashMap$EntryIterator.next(LinkedHashMap.java:413)
at java.util.LinkedHashMap$EntryIterator.next(LinkedHashMap.java:412)
at bitronix.tm.resource.jdbc.LruStatementCache.clear(LruStatementCache.java:171)
at bitronix.tm.resource.jdbc.JdbcPooledConnection.close(JdbcPooledConnection.java:150)
at bitronix.tm.resource.common.XAPool.expireStatefulHolder(XAPool.java:534)
at bitronix.tm.resource.common.XAPool.expireOrCloseStatefulHolders(XAPool.java:507)
at bitronix.tm.resource.common.XAPool.shrink(XAPool.java:485)
at bitronix.tm.timer.PoolShrinkingTask.execute(PoolShrinkingTask.java:42)
at bitronix.tm.timer.TaskScheduler.executeElapsedTasks(TaskScheduler.java:267)
at bitronix.tm.timer.TaskScheduler.run(TaskScheduler.java:247)

TransactionLogAppender's FileChannel is closed on interrupt and never reopened

When an interrupt happens on a thread during writing the transaction log, the underlying FileChannel is closed as a result. Any further use will throw a java.nio.channels.ClosedChannelException rendering the transaction manager unusable since the transaction logs are never reopened. The main issue here is that no other threads can use it any more.

Are there any solutions to situations like this?

Caused by: org.hibernate.TransactionException: JTA commit failed: 
        at org.hibernate.engine.transaction.internal.jta.JtaTransaction.doCommit(JtaTransaction.java:157) ~[hibernate-core.jar:4.3.8.Final]
        at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:180) ~[hibernate-core.jar:4.3.8.Final]
        ... 19 common frames omitted
Caused by: bitronix.tm.internal.BitronixSystemException: error logging status
        at bitronix.tm.BitronixTransaction.setStatus(BitronixTransaction.java:409) ~[btm.jar:3.0.0-SNAPSHOT]
        at bitronix.tm.BitronixTransaction.setStatus(BitronixTransaction.java:387) ~[btm.jar:3.0.0-SNAPSHOT]
        at bitronix.tm.twopc.Preparer.prepare(Preparer.java:64) ~[btm.jar:3.0.0-SNAPSHOT]
        at bitronix.tm.BitronixTransaction.commit(BitronixTransaction.java:281) ~[btm.jar:3.0.0-SNAPSHOT]
        at bitronix.tm.BitronixTransactionManager.commit(BitronixTransactionManager.java:183) ~[btm.jar:3.0.0-SNAPSHOT]
        at org.hibernate.engine.transaction.internal.jta.JtaTransaction.doCommit(JtaTransaction.java:152) ~[hibernate-core.jar:4.3.8.Final]
        ... 20 common frames omitted
Caused by: java.nio.channels.ClosedChannelException: null
        at sun.nio.ch.FileChannelImpl.ensureOpen(FileChannelImpl.java:99) ~[na:1.7.0_51]
        at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:717) ~[na:1.7.0_51]
        at bitronix.tm.journal.TransactionLogHeader.setPosition(TransactionLogHeader.java:205) ~[btm.jar:3.0.0-SNAPSHOT]
        at bitronix.tm.journal.TransactionLogAppender.writeLog(TransactionLogAppender.java:154) ~[btm.jar:3.0.0-SNAPSHOT]
        at bitronix.tm.journal.DiskJournal.log(DiskJournal.java:144) ~[btm.jar:3.0.0-SNAPSHOT]
        at bitronix.tm.BitronixTransaction.setStatus(BitronixTransaction.java:398) ~[btm.jar:3.0.0-SNAPSHOT]
        ... 25 common frames omitted

TaskScheduler breaks when 2 tasks with identical timestamps are added

If two tasks (e.g. 2 PoolShrinkingTask instances) are scheduled, via the TasksScheduler.addTask( ) method, and the tasks have an identical executionTime, then the second task will not be added to the scheduler's task set (even though debug logging indicates that the task has actually been scheduled).

Given that tasks are self scheduling, this means that no further tasks of this type will be scheduled for this resource.

As a concrete example, consider the following scenario.

DataSoure1 and DataSource2 are both being managed by Btx TM. The bitronix-task-scheduler thread attempts to schedule pool shrinking for both data sources

2016/08/11 11:51:28.384 DEBUG bitronix-task-scheduler TaskScheduler - scheduling pool shrinking task on an XAPool of resource DataSource1 with 5 connection(s) (4 still available) for Thu Aug 11 11:52:28 BST 2016
2016/08/11 11:51:28.384 DEBUG bitronix-task-scheduler TaskScheduler - task added? true
...
...
2016/08/11 11:51:28.384 DEBUG bitronix-task-scheduler TaskScheduler - scheduling pool shrinking task on an XAPool of resource DataSource2 with 1 connection(s) (0 still available) for Thu Aug 11 11:52:28 BST 2016
2016/08/11 11:51:28.384 DEBUG bitronix-task-scheduler TaskScheduler - task added? false

The above log snippet shows the Bitronix logging for scheduling a PoolShrinkingTask for each datasource. Note that the timestamps are identical (see the logging timestamps at the start of each line and you will see milliseconds are identical). The second line in each log pair above shows some diagnostic logging that I have added. The boolean value is the result of the call to add on the taskScheduler's Set.

This is happening due a combination of the Set implementation (ConcurrentSkipListSet) and the Task objects compareTo implementation which compares based upon executionTime.

This Set implementation uses the result of compareTo to both order the set, and decide if the value is already in the Set.

The net result of this, is that we have pools with a small minPoolSize, that never shrink back down again, if the duplicate timestamp issue occurs. I assume, but have not verified, that this will hold for transaction timeouts as well.

I'm assuming that the Set implementation is the correct implementation for this use-case, so I think that the best approach to fix this issue is to look at the Comparator. The following implementation will fix this, as it uses a discriminator (UUID) to decide the result, in the case of the timestamps being equal.

    public int compareTo(Task otherTask) {
        int compareResult = this.executionTime.compareTo(otherTask.executionTime);

        if (compareResult == 0) {
            compareResult = uniqueId.compareTo(otherTask.getUniqueId());
        }
        return compareResult;
    }

BTM masks original SQLException

We have experienced that BTM masks some SQLException’s if database errors occurs.
Further investigations of the source code has shown that is only occurs in LrcXAResource, and in all occurrences, every time around auto commit handling.

Are there an explicit reason why the original cause is masked away? The cause could contain any reason from internal DB errors to lost connection.

Snippet
try {
connection.setAutoCommit(true);
} catch (SQLException ex) {
throw new BitronixXAException("cannot reset autocommit on non-XA connection", XAException.XAER_RMERR);
}

ResourceBean volatile increment of int variable

The increment is not an atomic operation, even if we use a volatile variable.

private volatile transient int createdResourcesCounter;

public int incCreatedResourcesCounter() {
return this.createdResourcesCounter++;
}

This could be fixed by replacing the int variable with an AtomicInteger.

Documentation tweaks for "Resource loader configuration"

  1. It would be much less confusing to state explicitly that the value of bitronix.tm.resource.configuration is a filesystem path, not (as one might expect) a resource path, and so must be either an absolute path or expressed relative to the current directory of the JVM process. I had to search through the code to see why my attempts to set this were failing.

  2. It should be stated that the properties shown under "Configuring a JDBC pool" are representative but not definitive, and that one must go look at the documentation for the configured datasource type to find out what properties are actually recognized. For example, as discussed some years ago on some mailing list that I can't identify from its remains on Nabble, PGXADataSource does not have a URL property...but it does have a Url property which worked when I tried it.

Recovery fails to commit dangling transactions if there are no in-flight transactions

Test Case (BTM 2.1.4):

  • kill database before commit command can be sent to it (using debugger).
  • let thread continue to run
  • restart database
  • during recovery database reports transaction ID which is incomplete
  • Recoverer calls TransactionManagerServices.getTransactionManager().getOldestInFlightTransactionTimestamp() because transaction manager is running (line 137)
  • There are no in-flight transactions and so the TM returns Long.MIN_VALUE
  • Because the oldestInFlightTransactionTimestamp is now so low, the code on line 289 skips the dangling transaction which still needs to be committed.

The result is that the resource never has "commit" called again, unless BTM is restarted, or randomly a transaction is in-flight during recovery.

Why is the disk-journal split over two files?

The DiskJournal writes to two parts configured using bitronix.tm.journal.disk.logPart1Filename and bitronix.tm.journal.disk.logPart2Filename.

Why is this?
Should you configure these parts to reside on different physical disks?
Should these disks be local disks and not network mounts?

I can't seem to find any recommendations about this in the documentation.
Maybe I missed something?

Unable to get a connection from pool of a PoolingDataSource

I have deployed web application in Tomcat7. Everything was working fine for past 1 year. Now out of sudden I am getting this exception.
java.sql.SQLException: unable to get a connection from pool of a PoolingDataSource containing an XAPool of resource 5GV0UH57 with 1 connection(s) (1 still available) -failed-

Any thoughts on why this is happening ?

Add roadmap

Could you please add some hints on the roadmap? When could we roughly expect the first 3.0.x release? Since Codehaus has been shutdown, getting information/documentation about BTM 2.x became also pretty troublesome.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.