scalar-labs / btm Goto Github PK
View Code? Open in Web Editor NEWJTA Transaction Manager
License: Apache License 2.0
JTA Transaction Manager
License: Apache License 2.0
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.... ;-).)
Hi
We got app based on Oracle+BTM+SpringFramerwotk+Hibernate
and I see resource leak if XA transaction contain operation on database links.
Resurces are released on application kill.
I know. this is common problem http://stackoverflow.com/questions/5088934/how-can-i-close-oracle-dblinks-in-jdbc-with-xa-datasources-and-transactions-to-a
but how to add additional action 'alter session close database link ' after transaction commit /rollback
is there any way I could get database connection alone which is enlisted in a global transaction to rollback?
Are there any plans to release 3.0.0 version as 2.1.x does not work with hibernate 4.2 and above.
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.
useTmJoin not loaded by ResourceLoader. TestCase failed to assert because the default value is true.
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;
}
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
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)
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)
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
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);
}
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
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);
}
I used btm2.1.4
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.
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
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.
Hi,
Could you please upload bitronix 3.0 to central maven repository.
Thanks
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]
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!
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...
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.
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.
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:
What minimum jdk of BTM?
I cannot maven compile on jdk1.5. some source refer to jdk1.6.
Thank you.
Nicky
(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)
the transaction should not commit but still, I need to send the message to jms queue within the same transaction
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.
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
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!
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?
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?
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
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:
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)
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.
How to get the native connection (Native oracle connection in my case) from bitronix poolingdatasource inside spring @transactional Method
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
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
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 ?
Test Case (BTM 2.1.4):
The result is that the resource never has "commit" called again, unless BTM is restarted, or randomly a transaction is in-flight during recovery.
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.
native connection from PoolingDataSource of Bitronix
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?
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..
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.
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.
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)
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
.
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.
Dividing these two could get us the average wait time.
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.
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.
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://documentation.bonitasoft.com/ubuntu-openjdk-tomcat-mysql
http://bitronix-transaction-manager.10986.n7.nabble.com/tomcat-7-0-26-and-bitronix-td1155.html
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?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.