mysql事务(详解)
Mysql事務
一、事務存在的意義
1、事務定義
- 事務:事務是一個最小的不可在分的工作單元;通常一個事務對應一個完整的業務(例如銀行賬戶轉賬業務,該業務是一個最小的工作單元)
- 一個完整的業務需要批量的DML(insert、update、delete)語句共同聯合完成。
- 事務只和DML語句有關,或者說DML語句才有事務。這個和業務邏輯有關,業務邏輯不同,DML語句的個數不同。
2.事務是什么?
多個操作同時進行,那么同時成功,那么同時失敗。這就是事務。
事務有四個特性:一致性、持久性、原子性、隔離性
比如有一個訂單業務
1.訂單表當中添加一條記錄 2.商品數量數據更新(減少) 3…
當多個任務同時進行操作的時候,這些任務只能同時成功,或者同時失敗。
3.Mybatis關于事務的管理
MyBatis框架中的事務默認是手動提交的,也就是每次編寫程序都需要調用commit()方法提交事務
<transactionManager type="JDBC"></transactionManager> ====》程序員自己控制處理的提交和回滾二、事務的四大性質
原子性:事務是一個不可分割的工作單位,要么同時成功,要么同時失敗。例:當兩個人發起轉賬業務時,如果A轉賬發起,而B因為一些原因不能成功接受,事務最終將不會提交,則A和B的請求最終不會成功。
持久性:一旦事務提交,他對數據庫的改變就是永久的。注:只要提交了事務,將會對數據庫的數據進行永久性刷新。
隔離性:多個事務之間相互隔離的,互不干擾
一致性:事務執行接收之后,數據庫完整性不被破壞
注意:只有當前三條性質都滿足了,才能保證事務的一致性
刷臟:Mysql為了保證存儲效率,于是每次將要讀寫的文件是先存儲在緩存池中,對于數據的操作是在緩存池中,而mysql將會定期的刷新到磁盤中。
1、如何保證原子性:
? 首先:對于A和B兩操作要操作成功就一定需要更改到表的信息,如果如圖所示A語句操作成功,而B語句操作時出現斷電等其他情況終止了操作,所以此時兩個事務沒有操作成功,在沒有提交事務之前,mysql會先記錄跟新前的數據到undo log日志里面,當最終的因為操作不成功而發生事務回滾時,會從undo log日志里面先前存好的數據,重新對數據庫的數據進行數據的回退。
? undo log日志:(撤銷回退的日志)主要存儲數據庫更新之前的數據,用于作備份
2、如何保證事務的持久性:
通過重做日志:redo log日志,對于用戶將對發生了修改而為提交的數據存入了redo log日志中,當此時發生斷電等其他異常時,可以根據redo log日志重新對數據做一個提交,做一個恢復。
3、隔離性:
1事務的并發問題:
1、臟讀(讀未提交)
(1)、臟讀:事務A讀取到了事務已經修改但未提交的數據,這種數據就叫臟數據,是不正確的
2、讀已提交:(不可重復讀)
不可重復讀:對于事務A多次讀取同一個數據時,由于其他是事務也在訪問這個數據,進行修改且提交,對于事務A,讀取同一個數據時,有可能導致數據不一致,叫不可重復讀
3、可重復讀:(幻讀)
幻讀:原因:因為mysql數據庫讀取數據時,是將數據放入緩存中,當事務B對數據庫進行操作:例如刪除所有數據且提交時,事務A同樣能訪問到數據,這就產生了幻讀。
問題:解決了可重復讀,但是會產生一種問題,錯誤的讀取數據,對于其他事務添加的數據也將訪問不到
4、串行化
串行化:事務A和事務B同時訪問時,在事務A修改了數據,而沒有提交數據時,此時事務B想增加或修改數據時,只能等待事務A的提交,事務B才能夠執行。
**問題:**用戶的體驗十分的差,因為每次訪問時都要等待其他事務的提交才能操作
伴隨著對應的解決方案:
2事務的隔離等級:
隔離性的隔離級別
(1)、讀未提交:事物A和事物B,事物A未提交的數據,事物B可以讀取到。 這種隔離級別最低,這種級別一般是在理論上存在,數據庫隔離級別一般都高于該級別。 三種并發問題都沒解決。
set global transaction isolation level read uncommitted; #查看當前隔離級別 select @@global.tx_isolation,@@tx_isolation;(2)、讀已提交:事務A只能讀取到事務B提交的數據,這種級別可以避免“臟數據” ,這種隔離級別會導致“不可重復讀取” ,Oracle默認隔離級別
set global transaction isolation level read committed; 查看當前隔離級別 select @@global.tx_isolation,@@tx_isolation;(3)、可重復讀:- 事務A和事務B,事務A提交之后的數據,事務B讀取不到 - 事務B是可重復讀取數據 - 這種隔離級別高于讀已提交 - 換句話說,對方提交之后的數據,我還是讀取不到 - 這種隔離級別可以避免“不可重復讀取”,達到可重復讀取 - 比如1點和2點讀到數據是同一個 - MySQL默認級別 - 雖然可以達到可重復讀取,但是會導致“幻像讀”
set global transaction isolation level repeatable read; 查看當前隔離級別 select @@global.tx_isolation,@@tx_isolation;(4)、串行化:事務A和事務B,事務A在操作數據庫時,事務B只能排隊等待 這種隔離級別很少使用,吞吐量太低,用戶體驗差 這種級別可以避免“幻像讀”,每一次讀取的都是數據庫中真實存在數據,事務A與事務B串行, 而不并發
set global transaction isolation level serializable;查看當前隔離級別 select @@global.tx_isolation,@@tx_isolation;3隔離級別的一致性的關系:
三、事務的相關技術代碼
- 開啟事務:START TRANSACTION
- 事務的提交:COMMIT
ages/image-20220605111202527.png" alt=“image-20220605111202527” style=“zoom:80%;” />
三、事務的相關技術代碼
- 開啟事務:START TRANSACTION
- 事務的提交:COMMIT
- 事務的回滾:ROLLBACK (一旦事務提交失敗,我們需要將數據回滾到之前的狀態,需要用到rollback語句)
總結
以上是生活随笔為你收集整理的mysql事务(详解)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RxFFmpeg: Android Er
- 下一篇: vue router连续点击多次路由报错