posts - 193,  comments - 520,  trackbacks - 0
          ibatis DAO 框架提供了事務管理模塊。而這個事務管理可以應用到很多場合,包括JDBC、Hibernate、JTA、SQLMAP等。
          下面以最簡單的JDBC來分析一下其如何實現事務管理。
          首先來看一段代碼:
          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為我們提供的摸板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)

          http://www.aygfsteel.com/ronghao 榮浩原創,轉載請注明出處:)
          posted on 2006-01-20 17:50 ronghao 閱讀(7214) 評論(6)  編輯  收藏 所屬分類: 工作日志

          FeedBack:
          # re: ibatis DAO 事務探索
          2006-12-06 03:14 | ..
          無聊  回復  更多評論
            
          # re: ibatis DAO 事務探索
          2007-02-10 11:58 | yidinghe
          很棒!很有啟發性!謝謝!  回復  更多評論
            
          # re: ibatis DAO 事務探索
          2007-07-25 23:43 | zph
          不錯,謝謝  回復  更多評論
            
          # re: ibatis DAO 事務探索
          2008-03-26 10:37 | 屹礫
          先看一下,我也遇到了這個問題,一個事務操縱多個行為,不過事務總是沒有原子性,比較嚴重。  回復  更多評論
            
          # re: ibatis DAO 事務探索
          2009-10-23 13:19 | w
          @..
          人家辛苦發表- -說無聊真欠揍  回復  更多評論
            
          # re: ibatis DAO 事務探索
          2011-03-16 02:35 | leekiang
          這里的好幾個類在2.3版本里好像都去掉了  回復  更多評論
            
          <2006年1月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          關注工作流和企業業務流程改進。現就職于ThoughtWorks。新浪微博:http://weibo.com/ronghao100

          常用鏈接

          留言簿(38)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          常去的網站

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 台前县| 镇赉县| 奉新县| 宜川县| 临湘市| 安丘市| 兴和县| 饶平县| 班戈县| 华池县| 浑源县| 西城区| 长春市| 宁波市| 平陆县| 南京市| 阿拉善右旗| 衡山县| 中方县| 邹城市| 兴安盟| 察雅县| 江永县| 浙江省| 万山特区| 方城县| 观塘区| 来凤县| 平罗县| 新余市| 陇南市| 盘锦市| 惠州市| 山阳县| 哈尔滨市| 新化县| 红河县| 西宁市| 高清| 新疆| 旬邑县|