今天忽然想到一個問題,原來為了提高SQL Server性能,公司規定查詢語句一般都要加 WITH (NOLOCK)的
現在轉Java了,用了MySQL為啥不提這個事情了?
先在MySQL里寫了一個查詢語句,比樣子加了nolock,提示語法不正確,難道是用READUNCOMMITTED? 依然提示語法不正確,
看來MySQL是不支持nolock之類的語法
然后的問題變成了,為什么MySQL不需要支持nolock之類的語法,或者如果MySQL不支持nolock,修改記錄導致鎖表怎么辦?
所以我做了下面的實驗
給開了兩個MySQL連接,(順便插一句,因為用的客戶端是SQLyog,本以為跟SQL Server Management Studio一樣每個“詢問”就是一個連接,其實不是,每個連接都要“創建新連接”,我自己測試半天才發現這個問題)
第一個MySQL連接執行查詢
START TRANSACTION; UPDATE testtable SET NAME='newvalue' WHERE id=1
因為事務沒有提交,如果是SQLServer的默認情況下,第二個連接再查詢同一條記錄,肯定會被阻塞的。如果SQLServer查詢加了Nolock讀取到的是還未commit的臟值“newvalue”
第二個MySQL連接我執行查詢
SELECT * FROM `testtable`
我發現既沒有發生阻塞,也沒有發生臟讀,查詢到的是老的值,並沒有讀到未提交的新值newvalue
也就是說MySQL和SQLServer默認維護事務的機制是不同的,
SQLServer 默認情況下一個事務修改了某個值,在這個事務提交前,是阻塞其他連接來讀取這個修改中的值的,如果加nolock讀取到的是修改后為提交的值(也就是臟讀,因為可能這個值最終會回滾)
MySQL 默認情況下,一個事務修改了某個值,在這個事務提交前,不阻塞其他連接來讀取這個修改中的值,並且讀取到的是修改前的值。
對於互聯網公司,絕大多數場景,都不希望寫的事務來阻塞讀,
所以SQLServer建議加nolock
MySQL本身就不阻塞,nolock也就沒有意義了。。