首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

Ibatis中关于事宜的一个疑问的刨析——startTransaction的时候到底有没有与数据库交互

2013-04-07 
Ibatis中关于事务的一个疑问的刨析——startTransaction的时候到底有没有与数据库交互。sqlMapClient.startTr

Ibatis中关于事务的一个疑问的刨析——startTransaction的时候到底有没有与数据库交互。
sqlMapClient.startTransaction (); sqlMapClient.add (xxxxx); sqlMapClient.update (xxxxx); sqlMapClient.commitTransaction (); 看到这段代码你会不会有一个问题,sqlMapClient里面到底是怎么做的? public void startTransaction(int transactionIsolation) throws SQLException { getLocalSqlMapSession().startTransaction(transactionIsolation); }这里的?getLocalSqlMapSession()返回了一个SqlMapSession对象,这个对象非常重要,它管理了一次事务的状态,为什么重要后面会讲到。 public void begin(SessionScope session, int transactionIsolation) throws SQLException, TransactionException { Transaction trans = session.getTransaction(); TransactionState state = session.getTransactionState(); if (state == TransactionState.STATE_STARTED) { throw new TransactionException("TransactionManager could not start a new transaction. " + "A transaction is already started."); } else if (state == TransactionState.STATE_USER_PROVIDED) { throw new TransactionException("TransactionManager could not start a new transaction. " + "A user provided connection is currently being used by this session. " + "The calling .setUserConnection (null) will clear the user provided transaction."); } txThrottle.increment(); try { trans = transactionConfig.newTransaction(transactionIsolation);------------------------------- session.setCommitRequired(false); } catch (SQLException e) { txThrottle.decrement(); throw e; } catch (TransactionException e) { txThrottle.decrement(); throw e; } session.setTransaction(trans);---------------------------------------------- session.setTransactionState(TransactionState.STATE_STARTED); }?

?

注意用横线标出的那两句,首先创建了一个Transcaction,然后把它放入了session,为什么放入session,很重要,继续往下看。public class JdbcTransaction implements Transaction { private static final Log connectionLog = LogFactory.getLog(Connection.class); private DataSource dataSource; private Connection connection; private IsolationLevel isolationLevel = new IsolationLevel(); public JdbcTransaction(DataSource ds, int isolationLevel) throws TransactionException { // Check Parameters dataSource = ds; if (dataSource == null) { throw new TransactionException("JdbcTransaction initialization failed. DataSource was null."); } this.isolationLevel.setIsolationLevel(isolationLevel); } private void init() throws SQLException, TransactionException { // Open JDBC Transaction connection = dataSource.getConnection(); if (connection == null) { throw new TransactionException("JdbcTransaction could not start transaction. Cause: The DataSource returned a null connection."); } // Isolation Level isolationLevel.applyIsolationLevel(connection); // AutoCommit if (connection.getAutoCommit()) { connection.setAutoCommit(false); } // Debug if (connectionLog.isDebugEnabled()) { connection = ConnectionLogProxy.newInstance(connection); } } public void commit() throws SQLException, TransactionException { if (connection != null) { connection.commit(); } } public void rollback() throws SQLException, TransactionException { if (connection != null) { connection.rollback(); } } public void close() throws SQLException, TransactionException { if (connection != null) { try { isolationLevel.restoreIsolationLevel(connection); } finally { connection.close(); connection = null; } } } public Connection getConnection() throws SQLException, TransactionException { if (connection == null) { init(); } return connection; }}它在Init方法中调用了connection.setAutoCommit(false);来开始一个事务。但是Init方法并没有在构造方法中调用啊。那它是什么时候被调用的呢? 仔细看一下,是在getConnection()方法中调用。那getConnection()又是什么时候被调用呢。回头想一下,前面我们把这个创建出来的transcation对象放入了session,在事务中第一次操作数据库的时候,比如说add操作时,就会从session中把这个transcation对象拿出来,然后调用getConnection()方法。这时就会通知数据库开始一个事务。到现在为止,我们的问题应该清楚了。我刚开始提出来的两个猜想都不完全正确。不过第一个猜想更接近一点。正确的答案是:调用sqlMapClient.startTransaction时并没有通知数据库开始事务。但也不是最后commit时一次提交。而是在调用sqlMapClient.startTransaction后,第一次执行数据库操作时通知数据库开始事务,在我们的例子中,就是sqlMapClient.add (xxxxx)的这个时机。??

热点排行