標籤:交易 資料庫事務 java
在具體的工作中,有的事情需要被保持,不需要復原,有的工作需要復原,而這些邏輯,可以通過手動設定事務的復原點。
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中使用如下的語句設定交易回復點:
Savepoint sp = conn.setSavepoint();
Conn.rollback(sp);
Conn.commit();//復原後提交事務
3、JDBC使用事務範例之髒資料 以及讀取髒資料的原始碼
在JDBC代碼中示範銀行轉帳案例,有兩個銀行賬戶,A和B,各自有1000塊錢;A在銀行購買了一個VIP服務,花費10元錢;然後 A往B賬戶轉賬100塊。
在本範例中,購買VIP服務不需要復原,A往B賬戶轉賬,如果轉賬失敗,需要復原。
JAVA原始碼:
package com.transaction;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import com.db.EasyC3p0;
/**
*有兩個銀行賬戶,A和B,各自有1000塊錢;A在銀行購買了一個VIP服務,花費10元錢;然後 A往B賬戶轉賬100塊。
*在本範例中,購買VIP服務不需要復原,A往B賬戶轉賬,如果轉賬失敗,需要復原。
*
*@author 範芳銘
*/
public class EasySavepoint {
publicstatic void main(String[] args) throwsSQLException{
EasySavepointpoint = new EasySavepoint();
//首先對賬戶進行操作
point.OperAccount();
//查看賬戶執行情況
point.afterRunResult();
}
publicvoid OperAccount() throws SQLException{
Connectionconn = null;
PreparedStatementstmt = null;
ResultSetrs = null;
Savepointsp = null;
try{
conn= EasyC3p0.getConnection();
//通知數據庫開啟事務(start transaction)
//=================================
conn.setAutoCommit(false);
StringsqlAllMoney = " select sum(money) as money from ffm_account ";
StringsqlA_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賬戶購買VIP服務,花費10元
StringsqlA = "update ffm_account set money=money-100 where name=‘A‘";
stmt= conn.prepareStatement(sqlA);
stmt.executeUpdate();
//設定交易回復點
sp= conn.setSavepoint();
//簡單類比A往B賬戶轉賬:
sqlA= "update ffm_account set money=money-100 where name=‘A‘";
stmt= conn.prepareStatement(sqlA);
stmt.executeUpdate();
//系統中有B賬戶,但是發生了異常
//簡單粗暴的讓任務出現異常中斷
intx = 1/0;
Stringsqlc = "update ffm_account set money=money+100 where name=‘C‘";
stmt= conn.prepareStatement(sqlc);
stmt.executeUpdate();
conn.commit();
//簡單類比A往B賬戶 結束
//=================================
}catch (Exception e) {
//復原到設定的交易回復點
conn.rollback(sp);
//復原後要提交事務
conn.commit();
e.printStackTrace();
}finally {
EasyC3p0.close(conn,stmt, rs);
}
}
publicvoid afterRunResult(){
Connectionconn = null;
PreparedStatementstmt = null;
ResultSetrs = null;
try{
conn = EasyC3p0.getConnection();
//通知數據庫開啟事務(starttransaction)
//=================================
conn.setAutoCommit(false);
StringsqlAllMoney = " select sum(money) as money from ffm_account ";
StringsqlA_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"));
}
}catch (Exception e) {
e.printStackTrace();
}finally {
EasyC3p0.close(conn,stmt, rs);
}
}
}
4、運行結果
轉賬執行前,系統中全部金額為:2000
轉賬執行前,A的金額為:1000
java.lang.ArithmeticException: / by zero
atcom.transaction.EasySavepoint.OperAccount(EasySavepoint.java:64)
atcom.transaction.EasySavepoint.main(EasySavepoint.java:21)
轉賬執行後,系統中全部金額為:1900
轉賬執行後,A的金額為:900
系統雖然在運行中出現了異常,但是達到了預期的效果。
好記性不如爛筆頭25-JAVA處理資料庫事務(3) - 交易回復點