先來說說自己對事務(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ù)

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


接下來是事務(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種問題的解決方法用一張圖來展示

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

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

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

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

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

查詢隔離性

發(fā)現(xiàn)系統(tǒng)默認的是REPEATABLE READ, 因為這種隔離方式不支持臟讀,所以沒有辦法讀取到事務(wù)2中的改變
我們重新開始一個事務(wù),并將隔離等級改為READ UNCOMMITED

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

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

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

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

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

在事務(wù)1中再次執(zhí)行成績加20的操作,并查看值

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