事务没提交的数据查的出来吗?_“金三银四”面试官:说说事务的ACID,什么是脏读、幻读?...
一、事務
事務是數據庫管理系統執行過程中的一個邏輯單位,由一個有限的數據庫操作序列構成。--摘自百科
在MySQL里,事務是在引擎層面實現,比如MyIsam不支持,InnoDB支持
面試清單(Java崗):Java+JVM+數據庫+算法+Spring+中間件+設計模式?shimo.im二、ACID
提到事務,肯定會想到 ACID 是吧,自行感受一下概念,然后我們來講講隔離性的問題。
- 原子性:事務的所有操作要么全部成功,要么全部回滾。
- 一致性:總是從一個一致性的狀態轉換到另一個一致性的狀態。
- 隔離性:多個事務并發執行時,一個事務的執行不應影響其他事務的執行
- 持久性:已被提交的事務對數據庫的修改應該永久保存在數據庫中。
三、隔離級別
做了多年的 CRUDer,對這幾個詞真是不陌生,要不是出去面試,也真不會去了解。希望大家看完之后,面試的時候,不要慌,跟他剛。
實際上,這些場景都是出現在多個事務同時執行時的場景。
3.1 臟讀(Read Uncommitted)
通俗的講,一個事務在處理過程中讀取了另外一個事務未提交的數據。
你都還沒提交,我就讀到了你剛操作的數據,萬一你回滾了怎么辦,你說這臟不臟。
舉例:
假設打賞的邏輯是:① 我的賬戶+1元;② 你的賬戶-1元。
當你執行到第一個步驟,我去查詢我的賬戶已經是2元了,很開心!!!宣布請大家去擼串!!!但是最后扣款的時候發現你余額不足了,回滾了,我的1元沒了,就很難受!!
3.2 不可重復讀(Non-repeatable Read)
通俗的講,一個事務范圍內,多次查詢某個數據,卻得到不同的結果。
與臟讀的區別:臟讀是讀到未提交的數據,而不可重復讀讀到的卻是已經提交的數據,但實際上是違反了事務的一致性原則。
舉例:
假設我查了下賬戶余額,看到你們給小編打賞了1塊錢,很開心!!!宣布請大家去擼串!!!在付款之前,錢被另外一個人取走,又查詢到沒錢了,被留下來洗碗了!!!
因為我查詢完后,這條數據沒鎖住,又被別的事務更新了,導致當前事務每次都是讀到最新的數據。
3.3 幻讀
在Repeatable Read隔離級別下,一個事務可能會遇到幻讀(Phantom Read)的問題。
事務A讀取與搜索條件相匹配的若干行。事務B以插入或刪除行等方式來修改事務A的結果集,然后再提交。
舉例:
看到了嗎,在一個事務A中,第一次查詢某條記錄,是沒有的,但是,當試圖更新這條不存在的記錄時,竟然能成功,并且,再次讀取同一條記錄,它就神奇地出現了。
實際上,在InnoDB引擎中,對于索引的掃描,不僅鎖住掃描到的索引,而且還鎖住這些索引覆蓋的范圍(gap),因此這個范圍是內插入數據是不允許的。
四、mysql模擬事務隔離性測試
SELECT @@session.tx_isolation; SELECT @@tx_isolation; SET SESSION TRANSACTION ISOLATION LEVEL read uncommitted; SET SESSION TRANSACTION ISOLATION LEVEL read committed; SET SESSION TRANSACTION ISOLATION LEVEL repeatable read; SET SESSION TRANSACTION ISOLATION LEVEL serializable; start transaction;--建表 drop table AMOUNT; CREATE TABLE `AMOUNT` ( `id` varchar(10) NULL, `money` numeric NULL ) ; --插入數據 insert into amount(id,money) values('A', 800); insert into amount(id,money) values('B', 200); insert into amount(id,money) values('C', 1000); --測試可重復讀,插入數據 insert into amount(id,money) values('D', 1000);--設置事務 SET SESSION TRANSACTION ISOLATION LEVEL read uncommitted; SELECT @@tx_isolation; --開啟事務 start transaction;--臟讀演示,讀到其他事務未提交的數據 --案列1,事務一:A向B轉200,事務二:查看B金額變化,事務一回滾事務 update amount set money = money - 200 where id = 'A'; update amount set money = money + 200 where id = 'B';--不可重復讀演示,讀到了其他事務提交的數據 --案列2,事務一:B向A轉200,事務二:B向C轉200轉100 SET SESSION TRANSACTION ISOLATION LEVEL read committed; --開啟事務 start transaction; --兩個事務都查一下數據(轉賬之前需要,查一下金額是否夠滿足轉賬) select * from amount; --事務一:B向A轉200 update amount set money = money - 200 where id = 'B'; update amount set money = money + 200 where id = 'A';commit; --事務二:B向C轉200轉100 update amount set money = money - 100 where id = 'B'; update amount set money = money + 100 where id = 'C'; commit; --從事務二的角度來看,讀到了事務一提交事務的數據,導致金額出現負數--幻讀演示 --案列3,事務一:B向A轉200,事務二:B向C轉200轉100 SET SESSION TRANSACTION ISOLATION LEVEL repeatable read; --開啟事務 start transaction; --兩個事務都查一下數據(轉賬之前需要,查一下金額是否夠滿足轉賬) select * from amount; --事務一:B向A轉200 update amount set money = money - 200 where id = 'B'; update amount set money = money + 200 where id = 'A';commit; --事務二:B向C轉200轉100 update amount set money = money - 100 where id = 'B'; update amount set money = money + 100 where id = 'C'; commit; --從事務二的角度來看,讀到了事務一提交事務的數據,導致金額出現負數作者:Java2B原文鏈接:https://juejin.im/post/5e1417006fb9a047f3363c41
總結
以上是生活随笔為你收集整理的事务没提交的数据查的出来吗?_“金三银四”面试官:说说事务的ACID,什么是脏读、幻读?...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python数组初始化_Python N
- 下一篇: 玩家对《红色警戒RA4》阵营的大胆预测