事務(wù)
事務(wù)是并發(fā)控制的基本單位,指作為單個(gè)邏輯工作單元執(zhí)行的一系列操作剃幌,而這些邏輯工作需要滿足 ACID 特性关带。
- ACID
- 原子性(Atomicity):事務(wù)是數(shù)據(jù)庫邏輯工作單元葵硕,事務(wù)中包含的操作要么都執(zhí)行成功竞穷,要么都執(zhí)行失敗。
- 一致性(Consistency):事務(wù)執(zhí)行的結(jié)果必須是使數(shù)據(jù)庫數(shù)據(jù)從一個(gè)一致性狀態(tài)變到另外一種一致性狀態(tài)暖途。
- 隔離性(Isolation):一個(gè)事務(wù)的執(zhí)行過程中不能影響到其他事務(wù)的執(zhí)行卑惜,事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對(duì)其他事務(wù)是隔離的,并發(fā)執(zhí)行各個(gè)事務(wù)之間無不干擾驻售。
- 持續(xù)性(Durability):即一個(gè)事務(wù)執(zhí)一旦提交露久,它對(duì)數(shù)據(jù)庫數(shù)據(jù)的改變是永久性的。之后的其它操作不應(yīng)該對(duì)其執(zhí)行結(jié)果有任何影響欺栗。
JDBC 的事務(wù)控制
Connection 對(duì)象下的三個(gè)方法實(shí)現(xiàn)對(duì)事務(wù)的控制毫痕。
setAutoCommit()
- 設(shè)置為 false征峦,將所屬 Connection 對(duì)象的后續(xù)語句作為 JDBC 事務(wù)進(jìn)行處理,直到調(diào)用 commit() 方法消请。
- true 將所屬對(duì)象的后續(xù)每個(gè)語句作為單獨(dú)的 sql 語句進(jìn)行處理(默認(rèn)狀態(tài))栏笆。
commit()
提交事務(wù),使事務(wù)中的所有 sql 生效梯啤。
rollback()
回滾事務(wù)- 回滾到事務(wù)開始之前的狀態(tài)
conn = ds.getConnection();
// 開啟事務(wù)
conn.setAutoCommit(false);
psta = conn.prepareStatement("update user set account = ? where name = ?");
psta.setInt(1, 0);
psta.setString(2, "Mike");
psta.execute();
psta.setString(1, "100");
psta.setString(2, "Bob");
psta.execute();
// 提交事務(wù)
conn.commit();
在事務(wù)未提交之前竖伯,所有的 sql 語句都不會(huì)執(zhí)行存哲。
設(shè)置檢查點(diǎn)
setSavePoint()
設(shè)置數(shù)據(jù)庫保存點(diǎn)因宇,在出現(xiàn)異常后,可以回復(fù)到該點(diǎn)的狀態(tài)
rollback(SavePoint savePoint)
回復(fù)方法
public void Transaction() {
Connection conn = null;
PreparedStatement psta = null;
ResultSet rs = null;
Savepoint sp = null;
try {
conn = ds.getConnection();
// 開啟事務(wù)
conn.setAutoCommit(false);
psta = conn.prepareStatement("update user set account = ? where name = ?");
psta.setInt(1, 0);
psta.setString(2, "Mike");
psta.execute();
sp = conn.setSavepoint();
psta.setString(1, "100");
psta.setString(2, "Bob");
psta.execute();
// 提交事務(wù)
// conn.commit();
throw new SQLException();
} catch (SQLException e) {
try {
// 回滾事務(wù)到檢查點(diǎn)
conn.rollback(sp);
psta.setString(1, "100");
psta.setString(2, "GuoSi");
psta.execute();
conn.commit();
} catch (SQLException ex) {
ex.printStackTrace();
}
// e.printStackTrace();
} finally {
try {
if (conn != null)
conn.close();
if (psta != null)
psta.close();
if (rs != null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
設(shè)置 JDBC 中的隔離級(jí)別
getTranactionIlsoLation()
setTranactionIlsoLation()
各個(gè)隔離級(jí)別內(nèi)容在 MySQL 45講 第三講內(nèi)容中