1、事務
事務是訪問數(shù)據(jù)庫的一個操作序列及刻,數(shù)據(jù)庫應用系統(tǒng)通過事務集來完成對數(shù)據(jù)庫的存取镀裤。事務的正確執(zhí)行使得數(shù)據(jù)庫從一種狀態(tài)轉(zhuǎn)換成另一種狀態(tài)。
當操作序列中的所有操作都成功執(zhí)行時提茁,事務的狀態(tài)未成功淹禾。當任一操作失敗時,事務的狀態(tài)為失敗茴扁,此時必須將程序狀態(tài)返回至事務未執(zhí)行時的狀態(tài)铃岔,即回滾。
1.2 四個特性
原子性(Atomicity):事務中的所有操作是不可再分割的原子單位峭火,事務中的所有操作是一個整體毁习,或者整體執(zhí)行成功,亦或者整體執(zhí)行失敗卖丸。
一致性(Consistency):事務執(zhí)行后纺且,數(shù)據(jù)庫狀態(tài)與其他業(yè)務規(guī)則保持一致。如轉(zhuǎn)賬業(yè)務稍浆,無論執(zhí)行成功與否载碌,參與轉(zhuǎn)賬的兩個帳號余額值和應該是不變的。
隔離性(Isolation):在并發(fā)操作中衅枫,不同事務之間應該隔離開來嫁艇,每個并發(fā)中的事務的執(zhí)行不會相互干擾。
持久性(Durability):一旦事務提交成功弦撩,事務中的所有數(shù)據(jù)更新必須被持久化到數(shù)據(jù)庫中步咪,即使提交事務后,數(shù)據(jù)庫馬上崩潰益楼,在數(shù)據(jù)庫重新啟動時猾漫,也必須能保證通過某種機制恢復數(shù)據(jù)点晴。
1.3 數(shù)據(jù)庫的兩種事務模式
(1)自動提交模式:每個SQL語句都是一個獨立的事務,當數(shù)據(jù)庫系統(tǒng)執(zhí)行完一個SQL語句后悯周,會自動提交事務粒督。
(2)手動提交模式:必須由數(shù)據(jù)庫客戶程序顯示指定事務開始邊界和結(jié)束邊界。
默認是自動提交模式
1.4 數(shù)據(jù)庫讀寫中的并發(fā)事務問題
(1)臟讀(Dirty Read):在事務的執(zhí)行過程中禽翼,讀取到了其他事務的 未提交 的數(shù)據(jù)坠陈,即讀到了臟數(shù)據(jù)。
(2)不可重復讀(Unrepeatable Read):在事務的執(zhí)行過程中捐康,讀到了其他事務 修改后 的數(shù)據(jù)仇矾,換句話說在該事務中的不同時間點讀取到了不一致的數(shù)據(jù),即不可重復讀解总。
(3)幻讀/虛讀(Phantom Read):在事務的執(zhí)行過程中贮匕,讀取到了其他事務對 記錄數(shù) 修改后的數(shù)據(jù),對同一張表的兩次查詢的 COUNT(*) 不一致花枫。
不可重復讀與幻讀的區(qū)別:
不可重復讀:強調(diào)的是數(shù)據(jù) 內(nèi)容 的不一致刻盐,主要針對 UPDATE 的修改。
幻讀:強調(diào)的是 記錄數(shù) 的不一致劳翰,主要針對 INSERT/DELETE 的修改敦锌。
1.5 四個隔離級別
并發(fā)事務問題的產(chǎn)生原因是,未能遵守事務的隔離特性
(1)串行化(SERIALIZABLE):所有的事務依次逐個執(zhí)行佳簸,這樣事務之間就完全不可能產(chǎn)生干擾乙墙,也就是說,該級別可以防止臟讀生均、不可重復讀以及幻讀听想。但是這將嚴重影響程序的性能。通常情況下也不會用到該級別马胧。
(2)可重復讀(REPEATABLE_READ):該隔離級別表示一個事務在整個過程中可以多次重復執(zhí)行某個查詢汉买,并且每次返回的記錄都相同。即使在多次查詢之間有新增的數(shù)據(jù)滿足該查詢佩脊,這些新增的記錄也會被忽略蛙粘。該級別可以防止臟讀和不可重復讀。
(3)讀已提交(READ_COMMITTED):該隔離級別表示一個事務只能讀取另一個事務已經(jīng)提交的數(shù)據(jù)威彰。該級別可以防止臟讀出牧,這也是大多數(shù)情況下的推薦值。
(4)讀未提交(READ_UNCOMMITTED):該隔離級別表示一個事務可以讀取另一個事務修改但還沒有提交的數(shù)據(jù)抱冷。該級別不能防止臟讀和不可重復讀崔列,因此很少使用該隔離級別梢褐。
不同隔離級別可避免的并發(fā)問題
隔離級別 | 臟讀 | 不可重復讀 | 幻讀 |
---|---|---|---|
串行化 | Y | Y | Y |
可重復讀 | Y | Y | |
讀已提交 | Y | ||
讀未提交 |
2旺遮、應用
當一個事務未完成之前赵讯,寫操作不會真正寫入數(shù)據(jù)庫。同時需要注意耿眉,一個事務是以提交(commit)或者回滾(rollback)結(jié)束边翼,否則會發(fā)生死鎖,導致表被鎖死鸣剪,之后的任何正確操作都不會成功组底。
2.1 MySQL事務的應用
查看隔離級別語句:SELECT @@TX_ISOLATION;啟用事務:START TRANSACTION;設置隔離級別:set [global/session] transaction isolation level;提交:COMMIT;回滾:ROLLBACK;
# 開啟事務START TRANSACTION; # 執(zhí)行事務 SQL 語句 # SQL1 UPDATE Test_TableSET name = hhhWHERE id = 1; # SQL2 UPDATE Test_TableSET name = xxxWHERE id = 2; # 提交事務 COMMIT;
2.2 JDBC事務的應用
//設置隔離級別conn.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED); //啟用事務conn.setAutoCommit(false); //提交conn.commit(); //回滾conn.rollback();
try{ conn = jdbcTest.getConnection(sHostName, sPortNumber, sSid, userName, password);
conn.setTransactionIsolation(TRANSACTION_REPEATABLE_READ);
conn.setAutoCommit(false);
String SQL = "insert into Test_Table values('name1','age1')";
jdbcTest.excute(conn, SQL);
SQL = "insert into Test_Table values('name2','age2')";
jdbcTest.excute(conn, SQL);
conn.commit();}
catch (SQLException e){
if (conn != null) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
e.printStackTrace();}
finally{ if (conn != null)
{
try
{
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}}
原文作者:萌太隆
原文地址:https://blog.csdn.net/swl979623074/article/details/79416470