iBATIS DAO事务的理解要从iBATIS DAO 框架开始,它提供了事务管理模块。而这个事务管理可以应用到很多场合,包括JDBC、Hibernate、JTA、SQLMAP等。

创新互联专注于企业营销型网站、网站重做改版、会宁网站定制设计、自适应品牌网站建设、H5响应式网站、成都做商城网站、集团公司官网建设、成都外贸网站建设公司、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为会宁等各大城市提供网站开发制作服务。
下面以最简单的JDBC来分析一下其如何实现iBATIS DAO事务管理。
首先来看一段代码:
- public class OrderService {
 - private DaoManager daoManager;
 - private OrderDao orderDao;
 - public OrderService() {
 - daoManager = DaoConfig.getDaoManager();
 - orderDao = (OrderDao) daoManager.getDao(OrderDao.class);
 - }
 - public void method() {
 - try {
 - //a separate transaction
 - orderDao.method1(); //***个事务
 - daoManager.startTransaction(); //开始第二个事务
 - orderDao.method1();
 - orderDao.method2();
 - daoManager.commitTransaction();//提交第二个事务
 - } finally {
 - daoManager.endTransaction();
 - }
 - }
 - }
 
在method()方法里有着两个事务,如果在方法里不显式的调用daoManager.startTransaction(),则每个DAO的一次方法调用就是一个独立的事务。
iBATIS DAO事务,有两个核心接口DaoTransactionManager和DaoTransaction
对应着不同的数据库持久层实现,两个接口分别对应着不同实现
查看iBATIS 代码,可以发现这些manager实现事务,就是调用事务源的事务操作方法
- JdbcDaoTransactionManager
 - public void commitTransaction(DaoTransaction trans) {
 - ((JdbcDaoTransaction) trans).commit();
 - }
 - JdbcDaoTransaction
 - public JdbcDaoTransaction(DataSource dataSource) {
 - try {
 - connection = dataSource.getConnection();
 - if (connection == null) {
 - throw new DaoException("Could not start transaction.Cause: The DataSource returned a null connection.");
 - }
 - if (connection.getAutoCommit()) {
 - connection.setAutoCommit(false);
 - }
 - if (connectionLog.isDebugEnabled()) {
 - connection = ConnectionLogProxy.newInstance(connection);
 - }
 - } catch (SQLException e) {
 - throw new DaoException("Error starting JDBC transaction.Cause: " + e);
 - }
 - }
 - public void commit() {
 - try {
 - try {
 - connection.commit();
 - } finally {
 - connection.close();
 - }
 - } catch (SQLException e) {
 - throw new DaoException("Error committing JDBC transaction.Cause: " + e);
 - }
 - }
 
那么DaoTransactionManager以什么依据处理事务呢?DaoTransactionState看看DaoTransactionState的代码,非常简单,四个常量来表示事务处于的不同的状态
public static final DaoTransactionState ACTIVE = new DaoTransactionState();
public static final DaoTransactionState INACTIVE = new DaoTransactionState();
public static final DaoTransactionState COMMITTED = new DaoTransactionState();
public static final DaoTransactionState ROLLEDBACK = new DaoTransactionState();
那么实际程序中是如何控制事务的呢
在***段代码中,我们是这样取得DAO
orderDao = (OrderDao) daoManager.getDao(OrderDao.class);
实际daoManager返回的并不是orderDao的具体实现类,它返回的DaoProxy
DaoProxy
- public Object invoke(Object proxy, Method method, Object[] args)
 - throws Throwable {
 - Object result = null;
 - if (PASSTHROUGH_METHODS.contains(method.getName())) {
 - try {
 - result = method.invoke(daoImpl.getDaoInstance(), args);
 - } catch (Throwable t) {
 - throw ClassInfo.unwrapThrowable(t);
 - }
 - } else {
 - StandardDaoManager daoManager = daoImpl.getDaoManager();
 - DaoContext context = daoImpl.getDaoContext();
 - if (daoManager.isExplicitTransaction()) {
 - // Just start the transaction (explicit)
 - try {
 - context.startTransaction();
 - result = method.invoke(daoImpl.getDaoInstance(), args);
 - } catch (Throwable t) {
 - throw ClassInfo.unwrapThrowable(t);
 - }
 - } else {
 - // Start, commit and end the transaction (autocommit)
 - try {
 - context.startTransaction();
 - result = method.invoke(daoImpl.getDaoInstance(), args);
 - context.commitTransaction();
 - } catch (Throwable t) {
 - throw ClassInfo.unwrapThrowable(t);
 - } finally {
 - context.endTransaction();
 - }
 - }
 - }
 - return result;
 - }
 
看到这段代码就非常清楚了,每调用DAO的一次方法时,如果不显式的调用daoManager.startTransaction(),就会成为单独的一个iBATIS DAO事务。再看看iBATIS为我们提供的摸板JdbcDaoTemplate
- protected Connection getConnection() {
 - DaoTransaction trans = daoManager.getTransaction(this);
 - if (!(trans instanceof ConnectionDaoTransaction)) {
 - throw new DaoException("The DAO manager of type " + daoManager.getClass().getName() +
 - " cannot supply a JDBC Connection for this template, and is therefore not" +
 - "supported by JdbcDaoTemplate.");
 - }
 - return ((ConnectionDaoTransaction) trans).getConnection();
 - }
 
iBATIS控制多个DAO的事务实际是让这些DAO共用了一个DaoTransaction(ThreadLocal),一个Connection
这里是一个事务源的情况,如果多个事务源之间要完成全局事务,还是老老实实用分布式事务管理服务吧(jta)。
iBATIS DAO事务的相关信息就向你介绍到这里,之后的文章里我们还会提及的,请关注。