MySQL事務(wù)管理的作用詳解
1.為何使用事務(wù)管理
可以保證數(shù)據(jù)的完整性。事務(wù)(Transaction),就是將一組SQL語句放在同一批次內(nèi)去執(zhí)行,如果一個(gè)SQL語句出錯(cuò),則該批次內(nèi) 的所有SQL都將被取消執(zhí)行。
例子: 轉(zhuǎn)賬為例。
金庸向張無忌轉(zhuǎn)賬1000元。----在數(shù)據(jù)庫中修改兩個(gè)賬號的余額。

發(fā)生意外情況,則出現(xiàn)金庸減錢成功,而張無忌加錢失敗。 如何解決?
使用事務(wù)進(jìn)行解決,此時(shí)代碼執(zhí)行后金庸的錢沒有減,張無忌的錢也沒有加

2.數(shù)據(jù)庫事務(wù)的原理
如果不寫begin;commit;此時(shí)事務(wù)默認(rèn)自動(dòng)開啟,自動(dòng)提交; 在數(shù)據(jù)庫中 ,事務(wù)都是自動(dòng)提交的。事務(wù)的自動(dòng)提交就是 執(zhí)行sql語句完成之后 就立刻持久化到數(shù)據(jù)庫中。
begin;開始事務(wù)
rollback;回滾事務(wù)
commit;提交事務(wù)
當(dāng)我們添加了begin;和commit;后 事務(wù)的提交就從自動(dòng)變成手動(dòng)。因?yàn)橹型境鲥e(cuò),所以導(dǎo)致 commit;不執(zhí)行,也就是說緩沖區(qū)中的數(shù)據(jù)沒有到持久化 的數(shù)據(jù)庫中 。
public class Test {
public static void main(String[] args) {
Connection connection =null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
connection= DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai",
"root","123456");
connection.setAutoCommit(false);//開啟事務(wù)的手動(dòng)提交
String sql = "update tb_emp set salary=salary-1000 where name='金庸'";
PreparedStatement ps =connection.prepareStatement(sql);
ps.executeUpdate();
String sql1 = "update tb_emp setsalary=salary+1000 where name='張無忌'";
ps = connection.prepareStatement(sql1);
ps.executeUpdate();
connection.commit();//提交事務(wù)
}catch (Exception e){
try {
connection.rollback();//事務(wù)回滾 最初的狀態(tài)
} catch (SQLException throwables) {
throwables.printStackTrace();
}
e.printStackTrace();
}finally{
}
}
}3.什么是事務(wù)
從開啟到提交為一個(gè)事務(wù)。 由此可見,一個(gè)事務(wù)對應(yīng)一組業(yè)務(wù)。一個(gè)事務(wù)中間可以有一條sql,多條sql。 所以 一個(gè)業(yè)務(wù)開始之前 開啟事務(wù) 一個(gè)業(yè)務(wù) 結(jié)束之后 提交事務(wù)。 我們這個(gè)轉(zhuǎn)賬案例:需要幾個(gè)事務(wù)? 可以寫成兩個(gè)事務(wù),但是不合適。因?yàn)槲覀兊男枨?讓金庸減的同時(shí)讓張無忌加錢。只能寫 成一個(gè)事 務(wù)。 把多條sql語句當(dāng)作一件事情,要同時(shí)都能執(zhí)行到。
事務(wù)(Transaction),一般是指要做的或所做的事情。在計(jì)算機(jī)術(shù)語 中是指訪問并可能更新數(shù)據(jù)庫中各種數(shù)據(jù)項(xiàng)的一個(gè)程序執(zhí)行單元 (unit)。事務(wù)通常由高級數(shù)據(jù)庫操縱語言或編程語言(如SQL,C++或 Java)書寫的用戶程序的執(zhí)行所引起,并用形如begin transaction和 end transaction語句(或函數(shù)調(diào)用)來界定。事務(wù)由事務(wù)開始 (begin transaction)和事務(wù)結(jié)束(end transaction)之間執(zhí)行的全體 操作組成。
概括為: 事務(wù)是由一些列動(dòng)作組成,這些動(dòng)作要么都執(zhí)行,要么都不執(zhí)行。
3.1 事務(wù)的特性ACID
1、原子性(Atomicity): 事務(wù)開始后所有操作,要么全部做完,要么全部不做,不可能停滯在中間 環(huán)節(jié)。事務(wù)執(zhí)行過程中 出錯(cuò),會(huì)回滾到事務(wù)開始前的狀態(tài),所有的操作就 像沒有發(fā)生一樣。也就是說事務(wù)是一個(gè)不可分 割的整體,就像化學(xué)中學(xué)過 的原子,是物質(zhì)構(gòu)成的基本單位。
2、一致性(Consistency): 事務(wù)開始前和結(jié)束后,數(shù)據(jù)庫的數(shù)據(jù)完整性約束沒有被破壞,事務(wù)前后操 作數(shù)據(jù)是一致的 。比如 A向B轉(zhuǎn)賬,不可能A扣了錢,B卻沒收到。 能量守恒。
3、隔離性(Isolation): 一個(gè)事務(wù)的執(zhí)行不能被其他事務(wù)干擾。即一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù) 據(jù)對并發(fā)的其他事務(wù)是 隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾。 比如A正在從一張銀行卡中取錢,在A取錢的過 程結(jié)束前,B不能向這張卡 轉(zhuǎn)賬。 兩個(gè)事務(wù)之間是有隔離級別,隔離級別的不同會(huì)導(dǎo)致出現(xiàn)不同的問 題。此時(shí)產(chǎn)生三種讀: 臟讀 幻讀 不可重復(fù)讀。
4、持久性(Durability): 持久性(durability)。持久性也稱永久性(permanence),指一個(gè)事務(wù) 一旦提交,它對數(shù)據(jù)庫 中數(shù)據(jù)的改變就應(yīng)該是永久性的。接下來的其他操 作或故障不應(yīng)該對其有任何影響。
3.2 事務(wù)的并發(fā)問題
1、臟讀:
事務(wù)A讀取了事務(wù)B更新的數(shù)據(jù),然后B回滾操作,那么A讀取到的數(shù)據(jù)是臟數(shù)據(jù)。
2、不可重復(fù)讀
事務(wù)A多次讀取同一數(shù)據(jù),事務(wù)B在事務(wù)A多次讀取的過程中,對數(shù)據(jù)作了更新并提交,導(dǎo)致事務(wù)A多次讀取同一數(shù)據(jù)時(shí),結(jié)果不一致。
3、幻讀
已知有兩個(gè)事務(wù)A和B,A從一個(gè)表中讀取了數(shù)據(jù),然后B在該表中插入了一些新數(shù)據(jù),導(dǎo)致A再次讀取同一個(gè)表,就會(huì)多出幾行,簡單的說,一個(gè)事務(wù)中先后讀取一個(gè)范圍的記錄,但每次讀取的記錄數(shù)不同,稱之為幻象讀。
小結(jié):不可重復(fù)讀和幻讀容易混淆,不可重復(fù)讀側(cè)重于修改,幻讀側(cè)重于新增或刪除,解決不可重復(fù)讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表。
3.3 隔離級別
事務(wù)隔離性的等級:
查看事務(wù)的隔離等級:
語句:select @@global.transaction_isolation,@@transaction_isolation;

事務(wù)的隔離等級有四點(diǎn),每種隔離等級有其會(huì)出現(xiàn)的情況
1.Read Uncommitted(讀取未提交內(nèi)容)
在該隔離級別,所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果。本隔離級別很少用于實(shí)際應(yīng)用,因?yàn)樗男阅芤膊槐绕渌墑e好多少。讀取未提交的數(shù)據(jù),也被稱之為臟讀(Dirty Read)。
2.Read Committed(讀取提交內(nèi)容 也叫做不可重復(fù)讀)
這是大多數(shù)數(shù)據(jù)庫系統(tǒng)的默認(rèn)隔離級別(但不是MySQL默認(rèn)的)。它滿足了隔離的簡單定義:一個(gè)事務(wù)只能看見已經(jīng)提交事務(wù)所做的改變。這種隔離級別 也支持所謂的不可重復(fù)讀(Nonrepeatable Read),因?yàn)橥皇聞?wù)的其他實(shí)例在該實(shí)例處理其間可能會(huì)有新的commit,所以同一select可能返回不同結(jié)果。
一個(gè)事務(wù)讀某條數(shù)據(jù)讀兩遍,讀到的是不一樣的數(shù)據(jù),也就是說,一個(gè)事務(wù)在進(jìn)行中讀取到了其他事務(wù)對舊數(shù)據(jù)的修改結(jié)果,(比如說 我開一個(gè)事務(wù) 修改某條數(shù)據(jù) 先查后改 執(zhí)行修改動(dòng)作的時(shí)候發(fā)現(xiàn)這條數(shù)據(jù)已經(jīng)被別的事務(wù)刪掉了)
3.Repeatable Read(可重讀)
這是MySQL的默認(rèn)事務(wù)隔離級別,它確保同一事務(wù)的多個(gè)實(shí)例在并發(fā)讀取數(shù)據(jù)時(shí),會(huì)看到同樣的數(shù)據(jù)行。不過理論上,這會(huì)導(dǎo)致另一個(gè)棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當(dāng)用戶讀取某一范圍的數(shù)據(jù)行時(shí),另一個(gè)事務(wù)又在該范圍內(nèi)插入了新行,當(dāng)用戶再讀取該范圍的數(shù)據(jù)行時(shí),會(huì)發(fā)現(xiàn)有新的“幻影” 行。InnoDB和Falcon存儲(chǔ)引擎通過多版本并發(fā)控制(MVCC,Multiversion Concurrency Control)機(jī)制解決了該問題。
一個(gè)事務(wù)中,讀取到了其他事務(wù)新增的數(shù)據(jù),仿佛出現(xiàn)了幻象。(幻讀與不可重復(fù)讀類似,不可重復(fù)讀是讀到了其他事務(wù)update/delete的結(jié)果,幻讀是讀到了其他事務(wù)insert的結(jié)果)
4.Serializable(可串行化)
這是最高的隔離級別,它通過強(qiáng)制事務(wù)排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個(gè)讀的數(shù)據(jù)行上加上共享鎖。在這個(gè)級別,可能導(dǎo)致大量的超時(shí)現(xiàn)象和鎖競爭。

隔離級別越高,然后執(zhí)行效率越低。
4.Spring事務(wù)管理

到此這篇關(guān)于MySQL事務(wù)管理的作用詳解的文章就介紹到這了,更多相關(guān)MySQL事務(wù)管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于在sql中使用order by實(shí)現(xiàn)排序出錯(cuò)問題
這篇文章主要介紹了關(guān)于在sql中使用order by實(shí)現(xiàn)排序出錯(cuò)問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
Mysql主從同步Last_IO_Errno:1236錯(cuò)誤解決方法
最近遇到Mysql主從同步的Last_IO_Errno:1236錯(cuò)誤問題,然后在網(wǎng)上查找相關(guān)解決方案,這里分享給大家,供參考。2017-10-10
為什么Mysql?數(shù)據(jù)庫表中有索引還是查詢慢
這篇文章主要介紹了為什么Mysql數(shù)據(jù)庫表中有索引還是查詢慢,以?user_info?這張表來作為分析的基礎(chǔ),在?user_info?這張表上,我們分別創(chuàng)建了idx_name以及idx_phone?二級索引以及?idx_age_address?聯(lián)合索引展開詳細(xì)內(nèi)容,需要的小伙伴可以參考一下2022-05-05
Windows下MySQL?8.0.29?安裝和刪除圖文教程
這篇文章主要為大家詳細(xì)介紹了Windows下MySQL?8.0.29?安裝和刪除圖文教程,文中安裝步驟介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
sql如何使用group by分組,同時(shí)查詢其它字段
文章介紹了使用SQL的GROUP BY進(jìn)行分組查詢時(shí)的一些規(guī)則和技巧,主要強(qiáng)調(diào)了在SELECT后面的字段要么是聚合函數(shù)的一部分,要么必須包含在GROUP BY子句中,此外,文章還討論了如何在GROUP BY時(shí)查詢其他字段,通過使用MAX或MIN函數(shù)來實(shí)現(xiàn)2024-12-12

