Atomikos Forum |
|
When a transaction timeout occurs in Atomikos, the transaction is removed from the thread context and any additional database communication that is performed will be without transactional state and therefore commit! It might of course be something that I'm doing wrong, but I have a simple enough example below that reproduces it. I'm running Atomikos TransactionEssentials 3.2.4 (3.2.7 doesn't seem to have changed anything that would have affected this).
Regards, Olof Jönsson (Example follows:) import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import com.atomikos.icatch.jta.UserTransactionManager; import com.atomikos.jdbc.SimpleDataSourceBean; import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource; import javax.transaction.HeuristicMixedException; import javax.transaction.HeuristicRollbackException; import javax.transaction.NotSupportedException; import javax.transaction.RollbackException; import javax.transaction.SystemException; import javax.transaction.TransactionManager; import javax.sql.DataSource; /** * The ddl for running this example on MySql is as follows: * CREATE DATABASE test; * USE test; * GRANT ALL PRIVILEGES ON test.* TO test@localhost IDENTIFIED BY 'test'; * CREATE TABLE test ( id VARCHAR(32) NOT NULL, value VARCHAR(32), PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; * @author olof * */ public class Test { // Atomikos implementations private static UserTransactionManager utm; private static SimpleDataSourceBean sdsb; // Standard interfaces private static TransactionManager tm; private static DataSource ds; // initialize resources private static void init() throws SystemException { UserTransactionManager utm = new UserTransactionManager(); utm.init(); tm = utm; MysqlXADataSource xaDataSource = new MysqlXADataSource(); xaDataSource.setUrl("jdbc:mysql://localhost:3306/test"); xaDataSource.setUser("test"); xaDataSource.setPassword("test"); sdsb = new SimpleDataSourceBean(); sdsb.setXaDataSource(xaDataSource); ds = sdsb; } // release resources private static void shutdown() throws SQLException { sdsb.close(); utm.close(); utm.close(); } public static void main(String[] args) throws SQLException, NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException, InterruptedException { init(); tm.begin(); Connection c = ds.getConnection(); // The first statement Statement statement1 = c.createStatement(); statement1.execute("insert into test values ('key 1', 'value 1')"); statement1.close(); // The default timeout will be 10 seconds, so during this wait the first statement will roll back Thread.sleep(15000); // The second statement, this will apparently be performed outside a transactional context !?!? Statement statement2 = c.createStatement(); statement2.execute("insert into test values ('key 2', 'value 2')"); statement2.close(); c.close(); // IllegalStateException will be thrown tm.commit(); // The data will look like this in the DB: // mysql> select * from test; // +-------+---------+ // | id | value | // +-------+---------+ // | key 2 | value 2 | // +-------+---------+ // 1 row in set (0,00 sec) shutdown(); } } |