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

Brandon Goodin commented on IBATIS-259:
---------------------------------------

This should be posted to the user list not to a bug report. With a quick 
assesment I can see that you are starting a transaction, which establishes a 
connection on the thread. Then you replace that connection with your own and 
then expect it to reappear somehow when you get to the end. This looks to me 
like an innappropriate use of iBatis. What prompted you to use this approach? 
Please move this over to the user list.

> 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

Reply via email to