MySQL中的臟讀是指一個事務讀取了另一個未提交的事務中的數據。這種讀取的數據可能會受到未提交事務的回滾影響,所以臟讀是不能接受的。
臟讀的產生是因為MySQL的默認隔離級別是“可重復讀”,在這個隔離級別中,一個事務可以讀取另一個事務里已經提交的數據,但是卻不能讀取另一個事務中未提交的數據。如果需要讀取未提交的數據,可以使用“讀未提交”的隔離級別。
-- 線程A START TRANSACTION; SELECT * FROM table WHERE id = 1; -- 此時線程B修改了id為1的行的數據 COMMIT; -- 線程B START TRANSACTION; UPDATE table SET name = 'new_name' WHERE id = 1; -- 線程B未提交,此時線程A將會讀取到未提交的數據
從上面的代碼中可以看出,線程A在事務中讀取了id為1的行的數據,并沒有提交事務,然而此時線程B進行了一次修改數據的操作,但是沒有提交事務,這時線程A再次讀取id為1的行的數據時,將會讀取到未提交的數據,這樣的讀取就是臟讀。
為了避免臟讀的產生,可以將隔離級別設置為“讀已提交”或“可重復讀”,這樣在讀取數據時就可以保證不會讀取到未提交的數據。
-- 設置隔離級別為讀已提交 SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; -- 設置隔離級別為可重復讀 SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
總的來說,臟讀是數據庫中的一種嚴重問題,會影響到數據的完整性,因此在開發中需要注意隔離級別的設置,避免臟讀的產生。