[ http://issues.apache.org/jira/browse/IBATIS-259?page=all ] Sven Boden closed IBATIS-259: -----------------------------
Resolution: Invalid Assign To: Sven Boden Closed as announced as invalid. > 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.7, 2.1.6, 2.1.5 > Reporter: Paul Wilton > Assignee: Sven Boden > > 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