1. 幻讀。很多書和blog都提到mysql 的 tx_isolate (事務隔離)為repeatable read. 並且Mysql做了next-key lock的事情防止幻讀。但是如果你直接在事務中使用
SELECT * from [table];
SELECT * from [table] for update; SELECT * from [table] lock in share mode;
另外介紹一下幻讀:
幻讀就是當一個事務進行查詢時沒有發現該記錄,或者沒有發現該記錄被更改。結果在正在插入該記錄或者真正要改該記錄時,發現這條記錄已經被其他事務改過了。
例如
事務1, select * from [table];
這時進行事務2, insert into [table] select xx; commit;
事務1 再執行 select * from [table]; 這裡是沒有 事務2 的數據的。
這裡只要事務1再次執行 insert into [table] select xx; 這樣就發現這個行已經存在了;這就是幻讀。
2. 另外發現update的一個問題。如果使用事務, 首先select 數據然後再使用該數據進行update,有可能會有問題。一般使用 update [table] set col = col + value where ...這種形式進行更新,比select col from [table]; 取到col然後再進行update [table] set col = 剛才select 出的col value + value; 這樣更加正確,因為update自身可以加寫鎖。保證了不會幻讀。
3. 另外一個問題涉及到 limit. 例如 select * from [table] limit [len] offset [offset]; 如果這裡offset比較小,那麼這樣做是可以的。如果這裡offset很大,那麼這樣做類似於掃表。這裡需要使用where子句來加速。