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

                daoManager.startTransaction(); 
          //開始第二個事務(wù)

                orderDao.method1();
                orderDao.method2();

                daoManager.commitTransaction();
          //提交第二個事務(wù)
              }
           finally {
                daoManager.endTransaction();
              }

            }

            }
            在method()方法里有著兩個事務(wù),如果在方法里不顯式的調(diào)用daoManager.startTransaction(),則每個DAO的一次方法調(diào)用就是一個獨立的事務(wù)。
            ibatis DAO事務(wù),有兩個核心接口DaoTransactionManager和DaoTransaction
            對應(yīng)著不同的數(shù)據(jù)庫持久層實現(xiàn),兩個接口分別對應(yīng)著不同實現(xiàn)
            查看ibatis 代碼,可以發(fā)現(xiàn)這些manager實現(xiàn)事務(wù),就是調(diào)用事務(wù)源的事務(wù)操作方法

            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以什么依據(jù)處理事務(wù)呢?DaoTransactionState看看DaoTransactionState的代碼,非常簡單,四個常量來表示事務(wù)處于的不同的狀態(tài)
            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(); 
            那么實際程序中是如何控制事務(wù)的呢
            在第一段代碼中,我們是這樣取得DAO
            orderDao = (OrderDao) daoManager.getDao(OrderDao.class);
            實際daoManager返回的并不是orderDao的具體實現(xiàn)類,它返回的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;
            }
            看到這段代碼就非常清楚了,每調(diào)用DAO的一次方法時,如果不顯式的調(diào)用daoManager.startTransaction(),就會成為單獨的一個事務(wù)。再看看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的事務(wù)實際是讓這些DAO共用了一個DaoTransaction(ThreadLocal),一個Connection
           
            這里是一個事務(wù)源的情況,如果多個事務(wù)源之間要完成全局事務(wù),還是老老實實用分布式事務(wù)管理服務(wù)吧(jta)

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

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

          關(guān)注工作流和企業(yè)業(yè)務(wù)流程改進。現(xiàn)就職于ThoughtWorks。新浪微博:http://weibo.com/ronghao100

          常用鏈接

          留言簿(38)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          常去的網(wǎng)站

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 三亚市| 大埔县| 沙湾县| 通渭县| 滨州市| 嘉鱼县| 高邑县| 上虞市| 三亚市| 盈江县| 昌吉市| 大埔县| 周至县| 夏津县| 连山| 鹤峰县| 手游| 洪洞县| 神农架林区| 南皮县| 邹城市| 晋宁县| 腾冲县| 雷州市| 施甸县| 尤溪县| 郎溪县| 弋阳县| 东丽区| 南木林县| 文山县| 黄梅县| 隆德县| 江孜县| 绵阳市| 于田县| 昌邑市| 桐梓县| 东兴市| 磴口县| 峡江县|