posts - 11,  comments - 28,  trackbacks - 0
          本文參考了
          iBatis DAO入門與進(jìn)階(http://www.matrix.org.cn/resource/article/44/44058_iBatis+DAO.html
          ?iBatis DAO事務(wù)探索(http://www.aygfsteel.com/RongHao/archive/2006/01/20/28817.html

          今天繼續(xù)研究了JPetStore的持久層,其中由于看了一篇文章的誤導(dǎo),導(dǎo)致我對(duì)其中的事務(wù)處理深表懷疑。通過閱讀源代碼與看上面兩篇文章,對(duì)這個(gè)問題才認(rèn)識(shí)清楚。和我當(dāng)初預(yù)想的一致。
          第一、持久層的研究
          iBatis Dao的處理流程首先得到daoManager,它是通過文件配置的方式
          配置文件為com.ibatis.jpetstore.persistence.dao.xml
          <transactionManager?type="SQLMAP">
          ??????
          <property?name="SqlMapConfigResource"
          ????????value
          ="com/ibatis/jpetstore/persistence/sqlmapdao/sql/sql-map-config.xml"/>
          ????
          </transactionManager>

          ????
          <dao?interface="com.ibatis.jpetstore.persistence.iface.ItemDao"
          ??????implementation
          ="com.ibatis.jpetstore.persistence.sqlmapdao.ItemSqlMapDao"/>
          其中,具體的數(shù)據(jù)庫(kù)源的配置采用另外一個(gè)配置文件sql-map-config.xml,其余部分就是描述了各個(gè)實(shí)現(xiàn)dao接口的類(下文會(huì)具體的描述)。
          這個(gè)配置文件將被com.ibatis.jpetstore.persistence.DaoConfig.java 調(diào)用得到系統(tǒng)的daoManager,整個(gè)過程也就是一個(gè)工廠模式。得到了daoManger,通過它來統(tǒng)一管理對(duì)數(shù)據(jù)庫(kù)的操作。

          為了使用ibatis的DAO對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作,
          首先是定義了一批接口類,位于包:com.ibatis.jpetstore.persistence.iface 。然后是一批實(shí)現(xiàn)這個(gè)接口類,位于包:com.ibatis.jpetstore.persistence.sqlmapdao
          這些所有實(shí)現(xiàn)類繼承與sqlMapDaoTemplate,如下:
          public?class?ItemSqlMapDao?extends?BaseSqlMapDao?implements?ItemDao?{

          ??
          public?ItemSqlMapDao(DaoManager?daoManager)?{
          ????
          super(daoManager);
          ??}


          }

          public?class?BaseSqlMapDao?extends?SqlMapDaoTemplate?{

          ??
          protected?static?final?int?PAGE_SIZE?=?4;

          ??
          public?BaseSqlMapDao(DaoManager?daoManager)?{
          ????
          super(daoManager);
          ??}


          }
          sqlMapDaoTemplate是ibatis的一個(gè)核心類了,由它最終完成對(duì)數(shù)據(jù)庫(kù)的訪問。


          最后在業(yè)務(wù)邏輯層com.ibatis.jpetstore.service調(diào)用持久層完成對(duì)數(shù)據(jù)庫(kù)的訪問。

          public?class?OrderService?{

          ??
          private?DaoManager?daoManager;
          ??

          ??
          public?OrderService()?{
          ????daoManager?
          =?DaoConfig.getDaoManager();
          ????itemDao?
          =?(ItemDao)?daoManager.getDao(ItemDao.class);
          ????sequenceDao?
          =?(SequenceDao)?daoManager.getDao(SequenceDao.class);
          ????orderDao?
          =?(OrderDao)?daoManager.getDao(OrderDao.class);
          ??}

          }
          上面代碼即是,業(yè)務(wù)邏輯層根據(jù)dao.xml中指定的接口類型(ItemDao)得到它的實(shí)現(xiàn)類(ItemSqlMapDao),即是根據(jù)dao.xm中以下配置得到具體的dao實(shí)現(xiàn)類
          <dao?interface="com.ibatis.jpetstore.persistence.iface.ItemDao"
          ??????implementation
          ="com.ibatis.jpetstore.persistence.sqlmapdao.ItemSqlMapDao"/>


          然后通過這些實(shí)現(xiàn)類進(jìn)行數(shù)據(jù)庫(kù)訪問操作。如在OrderService下:

          public?void?insertOrder(Order?order)?{
          ????
          try?{
          ??????
          //?Get?the?next?id?within?a?separate?transaction
          ??????order.setOrderId(getNextId("ordernum"));

          ??????daoManager.startTransaction();

          ??????itemDao.updateAllQuantitiesFromOrder(order);
          ??????orderDao.insertOrder(order);

          ??????daoManager.commitTransaction();
          ????}
          ?finally?{
          ??????daoManager.endTransaction();
          ????}

          ??}

          其中還值得注意的是,在各個(gè)實(shí)現(xiàn)類中ItemSqlMapDao并不包含對(duì)事務(wù)的處理,所有對(duì)于事務(wù)的處理都是在業(yè)務(wù)邏輯層調(diào)用。這樣做的好處在于所有Dao的操作都是原子操作,方便進(jìn)行各種業(yè)務(wù)邏輯的組裝。(以前,我設(shè)計(jì)時(shí)候,這個(gè)地方?jīng)]有設(shè)計(jì)好)

          第二、事務(wù)處理的研究
          此處涉及到了事務(wù)的處理,來分析一下事務(wù)處理的過程。
          首先看一個(gè)事務(wù)處理的時(shí)序圖2005_12_18_224916_OkWdiCStgH.gif

          從這張時(shí)序圖可以看到事務(wù)的處理是由代理類DataProxy完成的,查看DataProxy的代碼

          ?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;
          ??}

          根據(jù)這段代碼應(yīng)該很清楚的知道Dao框架采用AOP模式,截獲所調(diào)用的方法,并檢查事務(wù)處理是否已經(jīng)顯式的開始執(zhí)行,如果沒有,它將調(diào)用事務(wù)管理器中的startTransaction()創(chuàng)建一個(gè)新的事務(wù)處理調(diào)用,然后執(zhí)行被截獲的方法,然后commitTransaction。如果有,則直接執(zhí)行所調(diào)用的方法。
          所以,在此Dao框架下,所有沒有顯式的通過startTransaction調(diào)用事務(wù)的方法,都是一個(gè)獨(dú)立的事務(wù)。如果要想在一個(gè)事務(wù)中完成幾次調(diào)用,必須自己通過DaoMangaer手動(dòng)處理事務(wù)。

          至此,ibatis的JpetshopStore的持久層運(yùn)行機(jī)制以及ibatis的Dao框架事務(wù)處理研究完畢。

          posted on 2007-01-16 21:15 滌生 閱讀(2809) 評(píng)論(2)  編輯  收藏


          FeedBack:
          # re: ibaits的JPetStore中持久層的研究、事務(wù)的處理
          2008-05-29 16:28 | 王天奇
          好 VERY GOOD  回復(fù)  更多評(píng)論
            
          # re: ibaits的JPetStore中持久層的研究、事務(wù)的處理
          2008-07-26 10:21 | xuxiaolei
          非常不錯(cuò)  回復(fù)  更多評(píng)論
            

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2007年1月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          常用鏈接

          留言簿(5)

          隨筆檔案

          UML

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 长葛市| 凤阳县| 莱西市| 永川市| 凌源市| 青冈县| 阜阳市| 蒙城县| 古蔺县| 合江县| 沐川县| 云安县| 永丰县| 武夷山市| 浦江县| 静乐县| 穆棱市| 大港区| 中宁县| 天门市| 建湖县| 大田县| 呈贡县| 珲春市| 蒲江县| 伊金霍洛旗| 咸丰县| 华宁县| 万全县| 广宁县| 施甸县| 金塔县| 延寿县| 溧阳市| 济宁市| 宁明县| 青川县| 恩平市| 宿松县| 滁州市| 天津市|