sql中的事務(wù)

先來說說自己對事務(wù)的理解。
首先自己對事務(wù)的理解就是數(shù)據(jù)庫中一個個完成的事件,我們在每次執(zhí)行數(shù)據(jù)庫的操作的時候,其實就是完成了一個事務(wù),其實我們在平時使用數(shù)據(jù)庫的時候,就已經(jīng)在使用事務(wù)了。因為數(shù)據(jù)庫默認是自動commit的,所以我們每執(zhí)行一次操作,便會自動提交事務(wù)。所以這里的重點其實是對事務(wù)的理解。以及手動commit事務(wù)的一些用法以及其作用。

首先是事務(wù)的ACID特性
即原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)
原子性指事務(wù)中的操作要么全部完成,要么全部失敗撤銷
一致性指事務(wù)中的操作都是在邏輯上正確的。
隔離性指多個事務(wù)之間不互相干擾,并發(fā)的事務(wù)之間要相互隔離。
持久性是指事務(wù)一旦提交,對數(shù)據(jù)庫的操作就是永久性的。

事務(wù)的使用

想要控制事務(wù)的話,就需要關(guān)閉自動提交,這里有兩種不同的方式來控制
首先是start transaction
它的意義是開始一個事務(wù),在這個語句之后的操作都屬于這個事務(wù)之內(nèi)的,只有在commit之后這些數(shù)據(jù)才會生效,而使用rollback后就會回滾。回到start transaction語句之前的狀態(tài)。


另一種就是set autocommit=0
使用這個語句之后就會將當前的模式轉(zhuǎn)換為手動提交,在這之后的所有sql語句,都需要commit之后才會永久性的提交
這里需要注意的是兩者的差別,start transaction是不管之前是否設(shè)置set autocommit,它都會開始一個手動提交的新事務(wù),直到commit之后,才會生效,rollback之后就會回滾。在commit或者rollback之后,autocommit會自動還原到start transaction之前的狀態(tài)。
在事務(wù)中還可以通過插入保存點來還原到保存點之前的狀態(tài),創(chuàng)建保存點的方法是SAVEPOINT point_name
刪除是RELEASE SAVEPOINT point_name
回到保存點之前的狀態(tài)是ROLLBACK TO SAVEPOINT point_name
例如之前作業(yè)里的表,我們查詢分數(shù)

image

新建事務(wù),對分數(shù)進行兩次修改,并在中間設(shè)置存檔點并返回存檔點
image

image
可以看到數(shù)據(jù)回到了存檔點之前的修改


接下來是事務(wù)當中概念較難理解的隔離性
首先,需要了解沒有隔離性所會發(fā)生的幾種問題
1、臟讀(Dirty Read)
一個事務(wù)處理過程里讀取了另一個未提交的事務(wù)中的數(shù)據(jù)
2、不可重復(fù)讀(NonRepeatable Read)
對于數(shù)據(jù)庫中的某個數(shù)據(jù),一個事務(wù)范圍內(nèi)多次查詢卻返回了不同的數(shù)據(jù)值,這是由于在查詢的間隔期間,另外一個事務(wù)修改并提交了該數(shù)據(jù)
3、幻讀(Phantom Read)
在一個事務(wù)中讀取到了別的事務(wù)插入的數(shù)據(jù),導致前后不一致
在事務(wù)中有四個隔離級別,它們對這3種問題的解決方法用一張圖來展示
image

當需要查看當前事務(wù)的隔離性是哪個等級的時候,可以使用SELECT @@transaction_isolation命令來查看
image

要修改當前事務(wù)的隔離性等級的時候,使用
SET session TRANSACTION ISOLATION LEVEL 隔離等級
image

我們來實際測試一下它的隔離性
我使用了之前作業(yè)里的score表
首先新建兩個事務(wù)
我們在這個事務(wù)中查詢分數(shù)
image

在第二個事務(wù)中將所有的分數(shù)都加上了20
image

再次查詢,發(fā)現(xiàn)并沒有查詢到事務(wù)2中所做的改變
image

查詢隔離性
image

發(fā)現(xiàn)系統(tǒng)默認的是REPEATABLE READ, 因為這種隔離方式不支持臟讀,所以沒有辦法讀取到事務(wù)2中的改變

我們重新開始一個事務(wù),并將隔離等級改為READ UNCOMMITED

image

再繼續(xù)新建事務(wù)2,修改表中數(shù)據(jù)
image

這次再在事務(wù)1中查詢,發(fā)現(xiàn)可以查詢到變化了
image



接下來還可以嘗試不可重復(fù)讀的效果
在事務(wù)1中將隔離等級設(shè)置為REPEATABLE READ,并查詢成績
image

在事務(wù)2中修改值并提交,查看到值已改變
image

再回到事務(wù)1中查詢,發(fā)現(xiàn)并沒有隨著變化
image

在事務(wù)1中再次執(zhí)行成績加20的操作,并查看值
image
可以發(fā)現(xiàn)并不是只加了20,事務(wù)2的修改也表現(xiàn)了出來,數(shù)據(jù)的一致性倒是沒有被破壞。select操作不會更新版本號,是快照讀(歷史版本);insert、update和delete會更新版本號,是當前讀(當前版本)。

mysql中事務(wù)隔離級別為serializable時會鎖表,插入記錄會顯示報錯,因此不會出現(xiàn)幻讀的情況,這種隔離級別并發(fā)性極低,開發(fā)中很少會用到。
隔離級別越高,越能保證數(shù)據(jù)的完整性和一致性,但是對并發(fā)性能的影響也越大。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容