You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ibatis.apache.org by "Sven Boden (JIRA)" <ib...@incubator.apache.org> on 2006/03/21 23:22:13 UTC

[jira] Commented: (IBATIS-259) SqlMapTransactionManager.setUserConnection(null) does not completely restore previous transaction state

    [ http://issues.apache.org/jira/browse/IBATIS-259?page=comments#action_12371319 ] 

Sven Boden commented on IBATIS-259:
-----------------------------------

To be closed around March 24th 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

>
> 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