MySQL的預設隔離級別是Repeatable read。會出現幻讀。
隔離級別 髒讀 不可重複讀 幻讀
==============================================================
未提交讀(Read uncommitted) 可能 可能 可能
已提交讀(Read committed) 不可能 可能 可能
可重複讀(Repeatable read) 不可能 不可能 可能
可序列化(Serializable ) 不可能 不可能 不可能
要解決幻讀問題,你首先要了解什麼是幻讀。
在一個事務中,已經對符合條件的資料進行了變更,但是提交前再次讀取的時候,還會有滿足要求的資料,因為在你的事務過程中,有其他的事務進行了新資料的提交,導致你又出現了滿足條件的資料。
比如:
begin
select count(*) from b where col=5;
比如一共三條
update b set col=10 where col=5;
提示已經更改了3行資料。
這時候已經修改但是沒有提交,
發現,又出現了一條。
commit
就會發現怎麼還有一條沒有更新到呢?
這就是幻讀。
如果你非要解決這個問題的話,set global transaction isolation level serializable;
這種情況下,在一個事務中執行的時候,其他事務只能等待。哪怕我只執行了一個select語句。
但是在序列化隔離級別的時候,併發效能極低,因此生產工作中,一般不建議配置該隔離級別,大多數都會配合應用,儘量去避免(實際上大多數應用都不存在這樣的問題)。就是非常嚴格的系統,也少有使用,就業務本身來說,是不需要大批次的實時更新,只有少量實時更新,執行速度非常快,也就不存在幻讀問題。
MySQL的預設隔離級別是Repeatable read。會出現幻讀。
隔離級別 髒讀 不可重複讀 幻讀
==============================================================
未提交讀(Read uncommitted) 可能 可能 可能
已提交讀(Read committed) 不可能 可能 可能
可重複讀(Repeatable read) 不可能 不可能 可能
可序列化(Serializable ) 不可能 不可能 不可能
要解決幻讀問題,你首先要了解什麼是幻讀。
在一個事務中,已經對符合條件的資料進行了變更,但是提交前再次讀取的時候,還會有滿足要求的資料,因為在你的事務過程中,有其他的事務進行了新資料的提交,導致你又出現了滿足條件的資料。
比如:
begin
select count(*) from b where col=5;
比如一共三條
update b set col=10 where col=5;
提示已經更改了3行資料。
這時候已經修改但是沒有提交,
select count(*) from b where col=5;
發現,又出現了一條。
commit
就會發現怎麼還有一條沒有更新到呢?
這就是幻讀。
如果你非要解決這個問題的話,set global transaction isolation level serializable;
這種情況下,在一個事務中執行的時候,其他事務只能等待。哪怕我只執行了一個select語句。
但是在序列化隔離級別的時候,併發效能極低,因此生產工作中,一般不建議配置該隔離級別,大多數都會配合應用,儘量去避免(實際上大多數應用都不存在這樣的問題)。就是非常嚴格的系統,也少有使用,就業務本身來說,是不需要大批次的實時更新,只有少量實時更新,執行速度非常快,也就不存在幻讀問題。