使用Mysql遇到的问题
1. 幻读。很多书和blog都提到mysql 的 tx_isolate (事务隔离)为repeatable read. 并且Mysql做了next-key lock的事情防止幻读。但是如果你直接在事务中使用
1 | SELECT * from [table]; |
这还是会有幻读发生。只有你在SELECT语句中加入锁才能防止幻读。例如:
1 | SELECT * from [table] for update; |
以上两句都可以防止幻读。第二句要优于第一句,因为加的是读锁而不是写锁。
另外介绍一下幻读:
幻读就是当一个事务进行查询时没有发现该记录,或者没有发现该记录被更改。结果在正在插入该记录或者真正要改该记录时,发现这条记录已经被其他事务改过了。
例如
1 | 事务1, select * from [table]; |
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子句来加速。