閑來(lái)無(wú)事,寫(xiě)一寫(xiě)事務(wù)的簡(jiǎn)單用法。
先假設(shè)有這樣一個(gè)場(chǎng)景,A轉(zhuǎn)賬給B若干人民幣,其中的流程可以簡(jiǎn)單理解為:系統(tǒng)先從A賬戶(hù)上扣除相應(yīng)金額,然后再加到B的賬戶(hù)上去??墒侨绻谄渲杏捎谀撤N原因?qū)е聸](méi)有將金額加到B的賬戶(hù)上,那么這若干人民幣就會(huì)不翼而飛。這時(shí)候就可以使用“事務(wù)”進(jìn)行處理。
可以簡(jiǎn)單的將事務(wù)理解為一個(gè)邏輯單元,在其中有一些操作邏輯,它們是一個(gè)整體,只要在其中的任一環(huán)節(jié)操作出了問(wèn)題,就可以回退到初始狀態(tài)。
主要涉及到的包及方法如下:
java.sql.Connection:
setAutoCommit(boolean); //設(shè)置是否自動(dòng)提交,一旦提交即可以理解為持久更改數(shù)據(jù)操作,如果設(shè)置為false,則需要手動(dòng)提交
commit(); //手動(dòng)提交更改,使之成為永久更改
rollback(); //回滾到初始狀態(tài)
rollback(Savepoint); //配合setSavepoint()可回滾到指定的狀態(tài)
setSavepoint(); //返回一個(gè)Savepoint,我將它理解成為一個(gè)狀態(tài)
一言不合貼代碼
package test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;
import org.junit.Test;
import utils.DBUtil;
//測(cè)試事務(wù)
public class A {
String a1 = "UPDATE money SET money=money-500 WHERE accountName='a';";
String a2 = "UPDATE money SET money=money+500 WHERE accountName='b';";
String a3 = "UPDATE1 money SET money=money+500 WHERE accountName='b';";
@Test
public void test(){
Connection conn = DBUtil.getConnection();
Savepoint sp = null;
try {
conn.setAutoCommit(false); //設(shè)置為不自動(dòng)提交
PreparedStatement pstmt;
//第一次執(zhí)行
pstmt = conn.prepareStatement(a1);
pstmt.executeUpdate();
pstmt = conn.prepareStatement(a2);
pstmt.executeUpdate();
sp = conn.setSavepoint(); //設(shè)置狀態(tài)
//第二次執(zhí)行
pstmt = conn.prepareStatement(a1);
pstmt.executeUpdate();
pstmt = conn.prepareStatement(a3);
pstmt.executeUpdate();
} catch (SQLException e) {
try {
conn.rollback(sp); //回滾到指定的狀態(tài)
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally{
try {
conn.commit(); //手動(dòng)提交
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}