<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://m.tkk7.com/Files/heyang/SpringTransaction.rar

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

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

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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 99视频在线免费观看| 豆国产96在线|亚洲| 国产麻豆成人传媒免费观看| 免费在线观看毛片| 日韩在线一区二区三区免费视频| 日本特黄特黄刺激大片免费| 亚洲av无码专区在线电影天堂| 永久黄网站色视频免费直播| 亚洲av无码有乱码在线观看| 四虎免费影院4hu永久免费| 免费一级毛片在线播放放视频| 中文字幕日韩亚洲| 午夜爽爽爽男女免费观看影院| 亚洲色图校园春色| 永久免费毛片在线播放| 国产精品亚洲av色欲三区| 又黄又大又爽免费视频| 免费无码又爽又刺激一高潮| 亚洲嫩模在线观看| 四虎成人免费观看在线网址 | 精品亚洲视频在线观看| 在线涩涩免费观看国产精品| 亚洲视频一区网站| 色www永久免费视频| caoporm碰最新免费公开视频| 亚洲一区精品中文字幕| 毛片a级毛片免费观看免下载 | 亚洲av综合avav中文| 一区二区无码免费视频网站 | 久久亚洲欧美国产精品| 亚洲无线码一区二区三区| 最近中文字幕2019高清免费| 亚洲色最新高清av网站| 亚洲综合熟女久久久30p| 97视频免费在线| 国产精品免费久久久久久久久| 亚洲人成电影网站| 中文字幕亚洲无线码a| 成人免费视频77777| 一个人看的www免费高清| 亚洲国产成人99精品激情在线|