標籤:資料庫事務   髒資料   java   
讀“髒”資料是指事務T1修改某一資料,並將其寫回磁碟,事務T2讀取同一資料後,T1由於某種原因被除撤消,而此時T1把已修改過的資料又恢複原值,T2讀到的資料與資料庫的資料不一致,則T2讀到的資料就為“髒”資料,即不正確的資料。
髒資料在比較複雜的互動式系統中,非常常見。
1、用JAVA處理資料庫事務的準備
要有一個能夠訪問資料庫的應用。下面的樣本都基於ORACLE進行。
create table ffm_account(
   id int primary key ,
   name varchar(32),
   money int
);
測試資料:
insert into ffm_account(id,name,money)values(1,‘A‘,1000);
insert into ffm_account(id,name,money)values(2,‘B‘,1000);
 
2、JDBC中使用事務
 
當Jdbc程式向資料庫獲得一個Connection對象時,預設情況下這個Connection對象會自動向資料庫提交在它上面發送的SQL語句。若想關閉這種預設提交方式,讓多條SQL在一個事務中執行,可使用下列的JDBC控制事務語句
Connection.setAutoCommit(false);//開啟事務(start transaction)
Connection.rollback();//復原事務(rollback)
Connection.commit();//提交事務(commit)
 
3、JDBC使用事務範例之髒資料 以及讀取髒資料的原始碼
在JDBC代碼中示範銀行轉帳案例,有兩個銀行賬戶,A和B,各自有1000塊錢; A往C賬戶轉賬100塊,然後去讀取A賬戶的錢,讀到了A賬戶只有900塊,但是C賬戶是不存在的,那麼這筆錢應該是轉賬失敗。
JAVA原始碼:
package com.transaction;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
 
import com.db.EasyC3p0;
 
/**
 *有兩個銀行賬戶,A和B,各自有1000塊錢;
 *A往C賬戶轉賬100塊,然後去讀取A賬戶的錢,讀到了A賬戶只有900塊,
 *但是C賬戶是不存在的,那麼這筆錢應該是轉賬失敗。
 *
 *@author 範芳銘
 */
public class EasyDirtyData {
    publicstatic void main(String[] args){
        Connectionconn = null;
        PreparedStatementstmt = null;
        ResultSetrs = null;
   
   try{
       conn =EasyC3p0.getConnection();
       //通知數據庫開啟事務(start transaction)
       conn.setAutoCommit(false);
       String sqlAllMoney = " select sum(money) as money from ffm_account";
       String sqlA_money = " select money from ffm_account " ;
       stmt = conn.prepareStatement(sqlAllMoney);
       rs = stmt.executeQuery();
       if (rs.next()){
           System.out.println("轉賬執行前,系統中全部金額為:" +rs.getInt("money"));
       }
       stmt = conn.prepareStatement(sqlA_money);
       rs = stmt.executeQuery();
       if (rs.next()){
           System.out.println("轉賬執行前,A的金額為:"+ rs.getInt("money"));
       }
       //簡單類比A往C賬戶轉賬:
       String sqlA = "update ffm_account set money=money-100 wherename=‘A‘";
       stmt = conn.prepareStatement(sqlA);
       stmt.executeUpdate();
       //系統中沒有C賬戶
       String sqlc = "update ffm_account set money=money+100 wherename=‘C‘";
       stmt = conn.prepareStatement(sqlc);
       stmt.executeUpdate();
       conn.commit();
       //簡單類比A往C賬戶 結束
       
       //轉賬結束後,看賬戶情況
       stmt = conn.prepareStatement(sqlAllMoney);
       rs = stmt.executeQuery();
       if (rs.next()){
           System.out.println("轉賬執行後,系統中全部金額為:" +rs.getInt("money"));
       }
       stmt = conn.prepareStatement(sqlA_money);
       rs = stmt.executeQuery();
       if (rs.next()){
           System.out.println("轉賬執行後,A的金額為:"+ rs.getInt("money"));
       }
       
   }catch (Exception e) {
       e.printStackTrace();
   }finally{
       EasyC3p0.close(conn, stmt, rs);
   }
    }
}
4、運行結果
轉賬執行前,系統中全部金額為:2000
轉賬執行前,A的金額為:1000
轉賬執行後,系統中全部金額為:1900
轉賬執行後,A的金額為:900
 
系統中的錢那裡去了,A:我的錢呢,還我錢!!!!!!!!!
好記性不如爛筆頭24-JAVA處理資料庫事務(2) - 髒資料