SqlMapTransactionManager.setUserConnection(null) does not completely restore
previous transaction state
-------------------------------------------------------------------------------------------------------
Key: IBATIS-259
URL: http://issues.apache.org/jira/browse/IBATIS-259
Project: iBatis for Java
Type: Bug
Components: SQL Maps
Versions: 2.1.5, 2.1.6, 2.1.7
Reporter: Paul Wilton
SqlMapTransactionManager.setUserConnection(null) does not completely restore
previous transaction state:
// 0) ... transaction manager setup as below
<transactionManager type="JDBC">
<dataSource type="JNDI">
<property name="DBInitialContext" value="java:comp/env"/>
<property name="DBLookup" value="/jdbc/dbname"/>
</dataSource>
</transactionManager>
PSEUDO CODE DEMONSTRATING PROBLEM AS FOLLOWS:
// 1) ... start transaction using DaoManager
DaoManager.startTransaction()
// perform some query using this transaction:
getSqlMapExecutor().queryForList(statementName, parameterObject);
// 2) ... perform some query with userConnection:
SqlMapExecutor executor = getSqlMapExecutor();
SqlMapTransactionManager tm = getSqlMapTransactionManager();
Connection userConn = null;
try {
// get a new connection from pool and set it to autocommit mode
true for this query
userConn = tm.getDataSource().getConnection();
tm.setUserConnection(userConn);
// execute the query
list = executor.queryForList(statementName, parameterObject);
} catch (SQLException e) {
// do something
} finally {
try {
// close the user connection
if (userConn!=null)
userConn.close();
// set the user connection back to null, so any transaction on
the other connection can be continued
tm.setUserConnection(null); // THIS SHOULD RESTORE THE
ORGINAL TRANSACTION STATE
} catch (SQLException e) {
// do something
}
}
// 3) ... perform another query using orginal transaction:
getSqlMapExecutor().queryForList(statementName, parameterObject);
// THIS FAILS - stacktracing with null pointer exception as follows:
java.lang.NullPointerException
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.autoEndTransaction(SqlMapExecutorDelegate.java:860)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:617)
at
com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:584)
at
com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:101)
at
com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:78)
at
nz.govt.nzqa.web.persistence.ibatis.sqlmap.BaseDaoImpl.executeQueryForList(BaseDaoImpl.java:63)
// 4) .. end original transaction using DaoManager - commit or rollback
DaoMoanager.commitTransaction();
DaoMoanager.endTransaction();
// This never executes due to previous failure
------------------
This failure appears to be caused by
SqlMapTransactionManager.setUserConnection(null) failing to restore the
original transaction state.
In the following methods of class SqlMapExecutorDelegate, pushSession(session)
resets the session thus setting the transaction manager for the session to
NULL. Consequently when step 3 (above) is executed ibatis stack traces.
public void setUserProvidedTransaction(SessionScope session, Connection
userConnection) {
if (session.getTransactionState() == TransactionState.STATE_USER_PROVIDED) {
session.recallTransactionState();
}
if (userConnection != null) {
Connection conn = userConnection;
session.saveTransactionState();
session.setTransaction(new UserProvidedTransaction(conn));
session.setTransactionState(TransactionState.STATE_USER_PROVIDED);
} else {
session.setTransaction(null);
pushSession(session);
}
}
protected void pushSession(SessionScope session) {
session.reset();
sessionPool.push(session);
}
EXPECTED OPERATION:
What I expect to happen when setUserConnection(null) is called is that the
original transaction (and thus connection) is restored in its entirety so that
subsequent queries can be made, and the transaction can be commited (or rolled
back) as a unit - with the query made on the user connection outside of this
transaction scope.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira