關於關係型資料庫隔離級別實現方式的思考
mysql中提供了讀未提交(read uncommitted 1級)、讀已提交(read committed 2級)、可重複讀(repeatable read 4級)、序列化(serializable 8級)四種隔離級別的選擇;
其中序列化最容易理解,也最容易實現,即每一次只允許一個使用者操作資料庫即可;
而讀未提交也容易實現,將資料庫不設定任何訪問和修改許可權即可。這樣的設定導致事務的原子性被打破了,一般很少使用該設定。
對於讀已提交,意思是隻要有使用者提交了對資料庫的修改(update、delete或者insert),都會對同一個session的查詢結果產生影響,所以同一個session的多次訪問,讀取到的資料內容和資料條數都有可能是不同的。我們只需遵循事務的原子性對資料庫更改就行了。
可重複讀,意思是其它使用者的update和delete對於同一個session的查詢不產生影響,但是還是會被insert影響,所以同一個session的多次訪問,讀取到的資料內容是一樣的,但是資料條數可能會因為insert而變多。
在每一條資料,都記錄其建立時間和最後一次修改時間;而在建立session時,也記錄session的建立時間,為了達到讀已提交或者可重複讀的要求,我們只需要在查詢到的結果中再通過時間來篩選一次即可。
具體實現的思路如下:
讀未提交:所有人都可以同時對資料庫操作,其事務中每一個步驟對資料庫都是立即生效的,而不是在提交時才有影響。
讀已提交:所有人都可以同時對資料庫操作,但是對於每一個使用者來說,先將資料庫中要操作的資料快取到本機,事務中的每一步操作都是面向本機的快取的,只有在最後提交的時候,才會同步到資料庫中。
可重複讀:每一條資料修改時都記錄一個時間戳,而新建的資料時間戳為0,使用者查詢時,也記錄建立session的時間戳。當查詢時,如果查詢到的某條記錄的時間戳比session的時間戳晚,說明這條記錄是在session建立後修改過的,那麼此條記錄就被捨棄。而新insert的資料,無論是再session建立前後,都不會被捨棄。這樣就達到了可重複讀的目的。
序列化:限定每次只有一個人訪問資料庫。只有這樣才能完全服從事務的ACID(原子性、一致性、隔離性、永續性)隔離級別,但是這樣做資料庫的效率就很低了。