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

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

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

    當柳上原的風吹向天際的時候...

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

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

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

    JDBC事務管理

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

    下面是使用事務處理的例程:

    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事務管理的問題

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

    使用Spring進行事務處理

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

    首先,在上下文定義文件中寫入JDBC事務管理器的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事務管理器會作為事務管理模板的一個屬性注入進入。

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

     

    而事務管理模板又作為一個屬性注入到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就具備了事務處理功能,下面轉賬函數(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("轉出的帳戶"+from+"余額不足");
         }

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

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

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

        
        
    // 如果成功,事務被提交
        return null;
       }

      }

     );
    }


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

    下面是模擬轉賬的具體代碼:

    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帳戶轉出4000給Bill,如果Andy帳戶余額低于4000將不會通過事務處理
    service.transfer(andy, bill, 4000);

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

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


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

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

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

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

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


    網站導航:
     
    主站蜘蛛池模板: 亚洲国产美女精品久久| 四虎影视在线看免费观看| 国产a不卡片精品免费观看| 男人扒开添女人下部免费视频| 亚洲日韩中文在线精品第一 | 成人精品综合免费视频| 亚洲不卡av不卡一区二区| 国产乱码免费卡1卡二卡3卡| 美景之屋4在线未删减免费| 亚洲Aⅴ无码专区在线观看q| 免费观看男人免费桶女人视频| 久久免费国产精品| 97se亚洲国产综合自在线 | 亚洲av色香蕉一区二区三区蜜桃| 亚洲一区爱区精品无码| 日韩精品成人无码专区免费| 中文字幕a∨在线乱码免费看| 狠狠色香婷婷久久亚洲精品| 亚洲日本va中文字幕久久| 好吊妞在线新免费视频| 可以免费观看的国产视频| 美女免费视频一区二区| 亚洲欧洲久久精品| 国产午夜亚洲不卡| 在线观看视频免费国语| 99热在线免费播放| 精品一区二区三区免费视频| 国产v亚洲v天堂a无| 午夜亚洲国产理论秋霞| 亚洲乱亚洲乱少妇无码| 在线观看视频免费国语| 色影音免费色资源| 免费av一区二区三区| 一级一黄在线观看视频免费| 亚洲日本VA午夜在线电影| 亚洲首页在线观看| 国产亚洲成AV人片在线观黄桃| 免费jjzz在线播放国产| 日本高清免费网站| 美女视频黄a视频全免费| 18女人腿打开无遮掩免费|