<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    當(dāng)柳上原的風(fēng)吹向天際的時候...

    真正的快樂來源于創(chuàng)造

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks

    在數(shù)據(jù)庫操作中,一項事務(wù)是由一條或者多條表達式所組成的一個不可分割的工作單元。
    事務(wù)必須遵循ACID原則,即:
    原子性(Atomicity):事務(wù)必須完全執(zhí)行或者完全不執(zhí)行,任何任務(wù)失敗都將導(dǎo)致整個事務(wù)回滾。
    一致性(Consistency):指原始數(shù)據(jù)庫的完整性,事務(wù)系統(tǒng)通過確保事務(wù)是原子性,隔離性和持續(xù)性來實現(xiàn)一致性。
    隔離性(Isolation):事物的執(zhí)行必須不受其它進程或者事務(wù)的干擾。
    持續(xù)性(Durabilty):意味著所有事務(wù)過程中的數(shù)據(jù)更改在事務(wù)成功之前必須寫入某些物理介質(zhì),確保系統(tǒng)崩潰時數(shù)據(jù)更改不會丟失。

    JDBC事務(wù)管理

    JDBC中引入一批語句對事務(wù)進行支持,它們是:
    Connection.setAutoCommit(True or fasle);設(shè)置事務(wù)是否自動提交,它的參數(shù)缺省是true.要進行事務(wù)處理的話,參數(shù)應(yīng)該設(shè)置為false.
    Connection.commit():從setAutoCommit語句開始,到commit語句之間算作一個數(shù)據(jù)庫事務(wù),其中的數(shù)據(jù)庫操作要么全成功要么全失敗.所有在調(diào)用commit方法之前的SQL語句都可以被回滾,然而,一旦commit()方法被調(diào)用,執(zhí)行過的SQL語句就不能再回滾.
    Rollback():事務(wù)回滾,如果事務(wù)中有一個步驟出現(xiàn)錯誤,那么調(diào)用這個方法將使數(shù)據(jù)庫恢復(fù)到執(zhí)行事務(wù)之前的狀態(tài),這樣,事務(wù)的原子性就得到了保證.

    下面是使用事務(wù)處理的例程:

    Connection conn=null;
    Statement statement
    =null;

    try{
      Class.forName(
    "org.gjt.mm.mysql.Driver");
      conn
    =DriverManager.getConnection("jdbc:mysql://127.0.0.1/test""root""hy");
      statement
    =conn.createStatement();
      
      conn.setAutoCommit(
    false);            
      
    int changeCount1=statement.executeUpdate(" update employee set salary=salary-10000 where NAME='郭德綱' ");
      
    int changeCount2=statement.executeUpdate(" update employee set salary=salary+10000 where NAME='于謙'  ");
            
      
    if(changeCount1==1 && changeCount2==1){
        conn.commit();
      }

      
    else{
        conn.rollback();
      }

    }

    catch(SQLException se){
      
    try{
        conn.rollback();
      }

      
    catch(Exception ex){
        ex.printStackTrace();
      }

    }


    JDBC事務(wù)管理的問題

    以上事務(wù)處理代碼是以數(shù)據(jù)庫的記錄為核心來考慮的,即使用Java代碼通過JDBC和SQL語句直接操作數(shù)據(jù)庫中的記錄,這種傳統(tǒng)方式在現(xiàn)代程序中已經(jīng)不多見,現(xiàn)代程序多把記錄歸納成領(lǐng)域?qū)ο螅缓笫褂妙I(lǐng)域?qū)ο髮?yīng)的DAO來完成領(lǐng)域?qū)ο笈c數(shù)據(jù)庫之間的交互。除了DAO層外,其它層次不與數(shù)據(jù)庫發(fā)生聯(lián)系。因此,上面的直接使用JDBC進行事務(wù)處理就不適用了,試想AccountService中有一個方法執(zhí)行兩個帳戶之間的轉(zhuǎn)賬,這個方法要具備事務(wù)功能必須繞過DAO層書寫底層的JDBC代碼,這是層次明晰紀律嚴明的系統(tǒng)所不能接受的,好在我們有Spring的事務(wù)處理可以幫我們擺脫兩難境地。

    使用Spring進行事務(wù)處理

    Spring對程序控制事務(wù)管理的支持和EJB有很大不同,EJB的事務(wù)管理和JTA密不可分,而Spring使用了一種回調(diào)機制,把真實的食物實現(xiàn)從事務(wù)代碼中抽象出來。實際上Spring的事務(wù)管理甚至不需要JTA,它也可以使用持久化機制本身多提供的事務(wù)管理支持。下面就是使用JDBC作為應(yīng)用的持久化機制的事務(wù)管理示例代碼:

    首先,在上下文定義文件中寫入JDBC事務(wù)管理器的bean定義。

    <bean id="transactionManager"
     class
    ="org.springframework.jdbc.datasource.DataSourceTransactionManager">
     
    <property name="dataSource">
      
    <ref bean="dataSource" />
     
    </property>
    </bean>


    它需要一個數(shù)據(jù)源的支持,數(shù)據(jù)源定義示例如下:

    <bean id="dataSource"
     class
    ="org.springframework.jdbc.datasource.DriverManagerDataSource">
     
    <property name="driverClassName"
      value
    ="org.gjt.mm.mysql.Driver">
     
    </property>
     
    <property name="url" value="jdbc:mysql://127.0.0.1/test">
     
    </property>
     
    <property name="username" value="root"></property>
     
    <property name="password" value="hy"></property>
    </bean>

     

    JDBC事務(wù)管理器會作為事務(wù)管理模板的一個屬性注入進入。

    <bean id="transactionTemplate"
     class
    ="org.springframework.transaction.support.TransactionTemplate">
     
    <property name="transactionManager">
      
    <ref bean="transactionManager" />
     
    </property>
    </bean>

     

    而事務(wù)管理模板又作為一個屬性注入到AccountService中。

    <bean id="accountService"
     class
    ="com.heyang.service.AccountService">
     
    <property name="dao" ref="accountDao"/> 
     
    <property name="table" value="SpringTransaction_Account"/>
     
    <property name="transactionTemplate">
      
    <ref bean="transactionTemplate" />
     
    </property>
    </bean>

     

    到這里,在transactionTemplate的幫助下,AccountService就具備了事務(wù)處理功能,下面轉(zhuǎn)賬函數(shù)的具體代碼:

    public void transfer(final Account from,final Account to,final int count){
     transactionTemplate.execute(
      
    new TransactionCallback(){
       
    public Object doInTransaction(TransactionStatus ts){
        
    try{
         
    if(count>from.getCount()){
          
    throw new Exception("轉(zhuǎn)出的帳戶"+from+"余額不足");
         }

         
         
    if(count>5000){
          
    throw new Exception("轉(zhuǎn)出的金額超過了中紀委限定的額度5000");
         }

         
         
    // 轉(zhuǎn)出帳戶減去轉(zhuǎn)賬金額
         from.setCount(from.getCount()-count);
         update(from);
         
         
    // 轉(zhuǎn)入帳戶加上轉(zhuǎn)賬金額
         to.setCount(to.getCount()+count);
         update(to);
        }

        
    catch(Exception ex){
         ex.printStackTrace();
         
    // 出現(xiàn)任何異常即回滾
         ts.setRollbackOnly();
        }

        
        
    // 如果成功,事務(wù)被提交
        return null;
       }

      }

     );
    }


    以上代碼中,執(zhí)行轉(zhuǎn)賬的業(yè)務(wù)代碼放在try塊中,如果全部代碼執(zhí)行成功,事務(wù)將會被提交;如果如下任何異常,事務(wù)會被回滾,出現(xiàn)異常前的任何修改點將被恢復(fù)到初始狀態(tài)。

    下面是模擬轉(zhuǎn)賬的具體代碼:

    ApplicationContext context=new ClassPathXmlApplicationContext("appCtx.xml");

    AccountService service
    =(AccountService)context.getBean("accountService"); 

    // 準備測試數(shù)據(jù)
    /* 建表語句如下
     * create table SpringTransaction_Account(
         id INTEGER(10) primary key not null , 
         name VARCHAR(255), 
         count INTEGER(255) 
      ) 
    */

    //Account andy=new Account("andy",3000);
    //service.create(andy);  
    //Account bill=new Account("bill",5000);
    //service.create(bill); 

    // 從數(shù)據(jù)庫取得帳戶Andy,11是其ID
    Account andy=service.getAccount("11");
    Account bill
    =service.getAccount("12");

    // 從Andy帳戶轉(zhuǎn)出4000給Bill,如果Andy帳戶余額低于4000將不會通過事務(wù)處理
    service.transfer(andy, bill, 4000);

    // 從Andy帳戶轉(zhuǎn)出1000給Bill,如果Andy帳戶余額低于1000將不會通過事務(wù)處理
    service.transfer(andy, bill, 1000);

    // 從Bill帳戶轉(zhuǎn)出5500給Andy,因為轉(zhuǎn)賬額度大于中紀委規(guī)定的5000因此不會通過事務(wù)處理
    service.transfer(bill, andy, 5500);


    以上就是使用Spring進行事務(wù)管理的主要流程,根據(jù)應(yīng)用的持久化機制的不同,Spring還提供了HibernateTransactionManger,JdoTransactionManger,OjbTransactionManger,JtaTransactionManger等事務(wù)管理器供用戶選擇,修改一下上面的transactionManager配置部分即可。

    本例中使用到的代碼下載:
    http://www.tkk7.com/Files/heyang/SpringTransaction.rar

    如果使用Hibernate作為程序持久介質(zhì)請下載:
    http://www.tkk7.com/Files/heyang/SpringHibernateTransaction.rar

    posted on 2009-02-13 10:54 何楊 閱讀(1100) 評論(0)  編輯  收藏

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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 免费看成人AA片无码视频吃奶| 99久久国产免费-99久久国产免费| 精品免费tv久久久久久久| 桃子视频在线观看高清免费完整| 国产成人aaa在线视频免费观看| 亚洲另类激情综合偷自拍图| 亚洲人成高清在线播放| 国产99久久久国产精免费| 222www在线观看免费| 免费在线观看中文字幕| 亚洲性无码av在线| 永久免费精品影视网站| 99久久99这里只有免费费精品| 国产性爱在线观看亚洲黄色一级片 | 亚洲国产一二三精品无码| 中文文字幕文字幕亚洲色| 91av免费在线视频| 无码日韩人妻av一区免费| 亚洲五月综合缴情在线观看| 亚洲日韩国产一区二区三区在线 | 国产gv天堂亚洲国产gv刚刚碰| 亚洲首页在线观看| 国产精品国产亚洲区艳妇糸列短篇 | 精品免费tv久久久久久久| 国产国产人免费视频成69大陆| 亚洲码一区二区三区| 一级毛片免费在线播放| 久久久久国色AV免费观看性色| 亚洲成a人片在线观看无码| 深夜特黄a级毛片免费播放| 免费看片在线观看| 精品亚洲综合久久中文字幕| 国产亚洲精品AAAA片APP| 114一级毛片免费| 久久国产精品亚洲综合 | 亚洲一区二区三区免费| 最近中文字幕mv免费高清电影| 国产av无码专区亚洲av桃花庵| 色婷婷六月亚洲综合香蕉| 成人免费视频69| 久久亚洲精品中文字幕三区|