MySQL事務(wù)管理的作用詳解
1.為何使用事務(wù)管理
可以保證數(shù)據(jù)的完整性。事務(wù)(Transaction),就是將一組SQL語(yǔ)句放在同一批次內(nèi)去執(zhí)行,如果一個(gè)SQL語(yǔ)句出錯(cuò),則該批次內(nèi) 的所有SQL都將被取消執(zhí)行。
例子: 轉(zhuǎn)賬為例。
金庸向張無(wú)忌轉(zhuǎn)賬1000元。----在數(shù)據(jù)庫(kù)中修改兩個(gè)賬號(hào)的余額。
發(fā)生意外情況,則出現(xiàn)金庸減錢(qián)成功,而張無(wú)忌加錢(qián)失敗。 如何解決?
使用事務(wù)進(jìn)行解決,此時(shí)代碼執(zhí)行后金庸的錢(qián)沒(méi)有減,張無(wú)忌的錢(qián)也沒(méi)有加
2.數(shù)據(jù)庫(kù)事務(wù)的原理
如果不寫(xiě)begin;commit;此時(shí)事務(wù)默認(rèn)自動(dòng)開(kāi)啟,自動(dòng)提交; 在數(shù)據(jù)庫(kù)中 ,事務(wù)都是自動(dòng)提交的。事務(wù)的自動(dòng)提交就是 執(zhí)行sql語(yǔ)句完成之后 就立刻持久化到數(shù)據(jù)庫(kù)中。
begin;開(kāi)始事務(wù)
rollback;回滾事務(wù)
commit;提交事務(wù)
當(dāng)我們添加了begin;和commit;后 事務(wù)的提交就從自動(dòng)變成手動(dòng)。因?yàn)橹型境鲥e(cuò),所以導(dǎo)致 commit;不執(zhí)行,也就是說(shuō)緩沖區(qū)中的數(shù)據(jù)沒(méi)有到持久化 的數(shù)據(jù)庫(kù)中 。
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);//開(kāi)啟事務(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='張無(wú)忌'"; 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ù)
從開(kāi)啟到提交為一個(gè)事務(wù)。 由此可見(jiàn),一個(gè)事務(wù)對(duì)應(yīng)一組業(yè)務(wù)。一個(gè)事務(wù)中間可以有一條sql,多條sql。 所以 一個(gè)業(yè)務(wù)開(kāi)始之前 開(kāi)啟事務(wù) 一個(gè)業(yè)務(wù) 結(jié)束之后 提交事務(wù)。 我們這個(gè)轉(zhuǎn)賬案例:需要幾個(gè)事務(wù)? 可以寫(xiě)成兩個(gè)事務(wù),但是不合適。因?yàn)槲覀兊男枨?讓金庸減的同時(shí)讓張無(wú)忌加錢(qián)。只能寫(xiě) 成一個(gè)事 務(wù)。 把多條sql語(yǔ)句當(dāng)作一件事情,要同時(shí)都能執(zhí)行到。
事務(wù)(Transaction),一般是指要做的或所做的事情。在計(jì)算機(jī)術(shù)語(yǔ) 中是指訪問(wèn)并可能更新數(shù)據(jù)庫(kù)中各種數(shù)據(jù)項(xiàng)的一個(gè)程序執(zhí)行單元 (unit)。事務(wù)通常由高級(jí)數(shù)據(jù)庫(kù)操縱語(yǔ)言或編程語(yǔ)言(如SQL,C++或 Java)書(shū)寫(xiě)的用戶(hù)程序的執(zhí)行所引起,并用形如begin transaction和 end transaction語(yǔ)句(或函數(shù)調(diào)用)來(lái)界定。事務(wù)由事務(wù)開(kāi)始 (begin transaction)和事務(wù)結(jié)束(end transaction)之間執(zhí)行的全體 操作組成。
概括為: 事務(wù)是由一些列動(dòng)作組成,這些動(dòng)作要么都執(zhí)行,要么都不執(zhí)行。
3.1 事務(wù)的特性ACID
1、原子性(Atomicity): 事務(wù)開(kāi)始后所有操作,要么全部做完,要么全部不做,不可能停滯在中間 環(huán)節(jié)。事務(wù)執(zhí)行過(guò)程中 出錯(cuò),會(huì)回滾到事務(wù)開(kāi)始前的狀態(tài),所有的操作就 像沒(méi)有發(fā)生一樣。也就是說(shuō)事務(wù)是一個(gè)不可分 割的整體,就像化學(xué)中學(xué)過(guò) 的原子,是物質(zhì)構(gòu)成的基本單位。
2、一致性(Consistency): 事務(wù)開(kāi)始前和結(jié)束后,數(shù)據(jù)庫(kù)的數(shù)據(jù)完整性約束沒(méi)有被破壞,事務(wù)前后操 作數(shù)據(jù)是一致的 。比如 A向B轉(zhuǎn)賬,不可能A扣了錢(qián),B卻沒(méi)收到。 能量守恒。
3、隔離性(Isolation): 一個(gè)事務(wù)的執(zhí)行不能被其他事務(wù)干擾。即一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù) 據(jù)對(duì)并發(fā)的其他事務(wù)是 隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾。 比如A正在從一張銀行卡中取錢(qián),在A取錢(qián)的過(guò) 程結(jié)束前,B不能向這張卡 轉(zhuǎn)賬。 兩個(gè)事務(wù)之間是有隔離級(jí)別,隔離級(jí)別的不同會(huì)導(dǎo)致出現(xiàn)不同的問(wèn) 題。此時(shí)產(chǎn)生三種讀: 臟讀 幻讀 不可重復(fù)讀。
4、持久性(Durability): 持久性(durability)。持久性也稱(chēng)永久性(permanence),指一個(gè)事務(wù) 一旦提交,它對(duì)數(shù)據(jù)庫(kù) 中數(shù)據(jù)的改變就應(yīng)該是永久性的。接下來(lái)的其他操 作或故障不應(yīng)該對(duì)其有任何影響。
3.2 事務(wù)的并發(fā)問(wèn)題
1、臟讀:
事務(wù)A讀取了事務(wù)B更新的數(shù)據(jù),然后B回滾操作,那么A讀取到的數(shù)據(jù)是臟數(shù)據(jù)。
2、不可重復(fù)讀
事務(wù)A多次讀取同一數(shù)據(jù),事務(wù)B在事務(wù)A多次讀取的過(guò)程中,對(duì)數(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ì)多出幾行,簡(jiǎn)單的說(shuō),一個(gè)事務(wù)中先后讀取一個(gè)范圍的記錄,但每次讀取的記錄數(shù)不同,稱(chēng)之為幻象讀。
小結(jié):不可重復(fù)讀和幻讀容易混淆,不可重復(fù)讀側(cè)重于修改,幻讀側(cè)重于新增或刪除,解決不可重復(fù)讀的問(wèn)題只需鎖住滿(mǎn)足條件的行,解決幻讀需要鎖表。
3.3 隔離級(jí)別
事務(wù)隔離性的等級(jí):
查看事務(wù)的隔離等級(jí):
語(yǔ)句:select @@global.transaction_isolation,@@transaction_isolation;
事務(wù)的隔離等級(jí)有四點(diǎn),每種隔離等級(jí)有其會(huì)出現(xiàn)的情況
1.Read Uncommitted(讀取未提交內(nèi)容)
在該隔離級(jí)別,所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果。本隔離級(jí)別很少用于實(shí)際應(yīng)用,因?yàn)樗男阅芤膊槐绕渌?jí)別好多少。讀取未提交的數(shù)據(jù),也被稱(chēng)之為臟讀(Dirty Read)。
2.Read Committed(讀取提交內(nèi)容 也叫做不可重復(fù)讀)
這是大多數(shù)數(shù)據(jù)庫(kù)系統(tǒng)的默認(rèn)隔離級(jí)別(但不是MySQL默認(rèn)的)。它滿(mǎn)足了隔離的簡(jiǎn)單定義:一個(gè)事務(wù)只能看見(jiàn)已經(jīng)提交事務(wù)所做的改變。這種隔離級(jí)別 也支持所謂的不可重復(fù)讀(Nonrepeatable Read),因?yàn)橥皇聞?wù)的其他實(shí)例在該實(shí)例處理其間可能會(huì)有新的commit,所以同一select可能返回不同結(jié)果。
一個(gè)事務(wù)讀某條數(shù)據(jù)讀兩遍,讀到的是不一樣的數(shù)據(jù),也就是說(shuō),一個(gè)事務(wù)在進(jìn)行中讀取到了其他事務(wù)對(duì)舊數(shù)據(jù)的修改結(jié)果,(比如說(shuō) 我開(kāi)一個(gè)事務(wù) 修改某條數(shù)據(jù) 先查后改 執(zhí)行修改動(dòng)作的時(shí)候發(fā)現(xiàn)這條數(shù)據(jù)已經(jīng)被別的事務(wù)刪掉了)
3.Repeatable Read(可重讀)
這是MySQL的默認(rèn)事務(wù)隔離級(jí)別,它確保同一事務(wù)的多個(gè)實(shí)例在并發(fā)讀取數(shù)據(jù)時(shí),會(huì)看到同樣的數(shù)據(jù)行。不過(guò)理論上,這會(huì)導(dǎo)致另一個(gè)棘手的問(wèn)題:幻讀 (Phantom Read)。簡(jiǎn)單的說(shuō),幻讀指當(dāng)用戶(hù)讀取某一范圍的數(shù)據(jù)行時(shí),另一個(gè)事務(wù)又在該范圍內(nèi)插入了新行,當(dāng)用戶(hù)再讀取該范圍的數(shù)據(jù)行時(shí),會(huì)發(fā)現(xiàn)有新的“幻影” 行。InnoDB和Falcon存儲(chǔ)引擎通過(guò)多版本并發(fā)控制(MVCC,Multiversion Concurrency Control)機(jī)制解決了該問(wèn)題。
一個(gè)事務(wù)中,讀取到了其他事務(wù)新增的數(shù)據(jù),仿佛出現(xiàn)了幻象。(幻讀與不可重復(fù)讀類(lèi)似,不可重復(fù)讀是讀到了其他事務(wù)update/delete的結(jié)果,幻讀是讀到了其他事務(wù)insert的結(jié)果)
4.Serializable(可串行化)
這是最高的隔離級(jí)別,它通過(guò)強(qiáng)制事務(wù)排序,使之不可能相互沖突,從而解決幻讀問(wèn)題。簡(jiǎn)言之,它是在每個(gè)讀的數(shù)據(jù)行上加上共享鎖。在這個(gè)級(jí)別,可能導(dǎo)致大量的超時(shí)現(xiàn)象和鎖競(jìng)爭(zhēng)。
隔離級(jí)別越高,然后執(zhí)行效率越低。
4.Spring事務(wù)管理
到此這篇關(guān)于MySQL事務(wù)管理的作用詳解的文章就介紹到這了,更多相關(guān)MySQL事務(wù)管理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL函數(shù)一覽_MySQL函數(shù)全部匯總
下面小編就為大家?guī)?lái)一篇MySQL函數(shù)一覽_MySQL函數(shù)全部匯總。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06centos 7系統(tǒng)下編譯安裝 mysql5.7教程
因?yàn)镸ysql5.7的更新特性還是非常多,所以這篇文章就給大家介紹以下在centos上面編譯安裝mysql5.7的教程。本文給大家介紹的步驟還是相對(duì)來(lái)說(shuō)比較詳細(xì)的,相信對(duì)大家具有一定的參考借鑒價(jià)值,有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。2016-11-11MySQL拋出Incorrect string value異常分析
從上至下統(tǒng)一用上UTF-8就高枕無(wú)憂(yōu),今天還是遇到字符的異常,本文將介紹解決方法2012-11-11詳談innodb的鎖(record,gap,Next-Key lock)
下面小編就為大家?guī)?lái)一篇詳談innodb的鎖(record,gap,Next-Key lock)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03mysql 數(shù)據(jù)庫(kù)中my.ini的優(yōu)化 2G內(nèi)存針對(duì)站多 抗壓型的設(shè)置
mysql數(shù)據(jù)庫(kù)中my.ini的優(yōu)化,2G內(nèi)存,針對(duì)站多,抗壓型的設(shè)置.大家可以借鑒下。2009-08-08MySQL遠(yuǎn)程無(wú)法連接的一些常見(jiàn)原因總結(jié)
有的小伙伴發(fā)現(xiàn)自己的mysql無(wú)法正常連接遠(yuǎn)程服務(wù)器,下面這篇文章主要給大家介紹了關(guān)于MySQL遠(yuǎn)程無(wú)法連接的一些常見(jiàn)原因,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09通過(guò)代碼實(shí)例了解頁(yè)面置換算法原理
這篇文章主要介紹了通過(guò)代碼實(shí)例了解頁(yè)面置換算法原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08