项目开发-iBatis事宜源码之开启新事务
项目开发-iBatis事务源码之开启新事务
iBatis事务源码流程整理如下。主要包括事务的使用以及各个方法的调用过程。
iBatis的事务使用
iBatis只有对单个的增、删、改操作添加了默认事务处理过程,如果客户端没有开启事务,那么就为这些操作自动添加事务,以保证这些修改操作会被提交。因此,客户端多条语句的原子操作,需要自己调用iBatis的事务方法,将这些操作封装在事务中来实现。典型的事务使用代码如下:
* try { * <b>sqlMap.startTransaction()</b> * Employee emp2 = new Employee(); * // ...set emp2 data * Integer generatedKey = (Integer) <b>sqlMap.insert ("insertEmployee", emp2)</b>; * emp2.setFavouriteColour ("green"); * <b>sqlMap.update("updateEmployee", emp2)</b>; * <b>sqlMap.commitTransaction()</b>; * } finally { * <b>sqlMap.endTransaction()</b>; * }这是SqlMapClient类的注释部分,该类的注释本质上就是iBatis的SqlMapClient的API文档。例如:开户流程中需要保证账户和人员信息的原子性。示例如下
SqlMapClient client = SimpleExample.getInstance(); try { client.startTransaction(); SimpleExample.insertPerson(p); SimpleExample.insertAccount(account); client.commitTransaction(); } catch (SQLException execption) { }finally{ try { client.endTransaction(); } catch (SQLException e) { e.printStackTrace(); } }
startTransaction
1)SqlMapClientImpl提供的startTransaction()方法
public void startTransaction() throws SQLException { getLocalSqlMapSession().startTransaction(); }
protected SqlMapSessionImpl getLocalSqlMapSession() { SqlMapSessionImpl sqlMapSession = (SqlMapSessionImpl) localSqlMapSession.get(); if (sqlMapSession == null || sqlMapSession.isClosed()) { sqlMapSession = new SqlMapSessionImpl(this); localSqlMapSession.set(sqlMapSession); } return sqlMapSession; }2)SqlMapSessionImpl类的startTransaction()
public SqlMapSessionImpl(SqlMapClientImpl client) { this.delegate = client.getDelegate(); this.sessionScope = this.delegate.beginSessionScope(); this.sessionScope.setSqlMapClient(client); this.sessionScope.setSqlMapExecutor(client); this.sessionScope.setSqlMapTxMgr(client); this.closed = false; }
public void startTransaction() throws SQLException { delegate.startTransaction(sessionScope); }3)SqlMapExecutorDelegate的startTransaction()
public void startTransaction(SessionScope sessionScope) throws SQLException { try { txManager.begin(sessionScope); } catch (TransactionException e) { throw new NestedSQLException("Could not start transaction. Cause: " + e, e); } }4)TransactionManager的begin()方法
public void begin(SessionScope sessionScope, int transactionIsolation) throws SQLException, TransactionException { Transaction trans = sessionScope.getTransaction(); TransactionState state = sessionScope.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."); } trans = config.newTransaction(transactionIsolation); sessionScope.setCommitRequired(false); sessionScope.setTransaction(trans); sessionScope.setTransactionState(TransactionState.STATE_STARTED); }5)TransactionConfig的newTransaction()代码
public Transaction newTransaction(int transactionIsolation) throws SQLException, TransactionException { return new JdbcTransaction(dataSource, transactionIsolation); }该操作执行完成后,SqlMapSessionImpl的属性SessionScope中存储了当前会话的事务的信息:当前新建的事务对象,以及事务的状态(新建状态)和提交标识(false)。