在做项目中的数据统计分析的时候,需要对访问量进行统计,对某个字段的累加,mysql处理累加的时候一般是先查询后加1,这样在大访问量的时候对于select与update的时候会出现数据的不准确性:
伪代码如下
$data = select num from test where id=1;
update test set num = $data['num']+1 where id=1;
处理该问题要掌握的几个概念
共享锁:读的时候不能写---s锁
排他锁:写的时候不能读---x锁
快照读:读取历史可见版本,不加锁,其他事务可修改该记录
当前读:最新版本数据,并给该记录加锁,保证其他事物不会修改该记录
脏读:一个事务读取到另一个事务中未提交的数据,这个事务回滚,形成脏读
幻读:事务A读再次,一次事务B未提交,一次提交,形成幻读
解决方法:
1、加事务,mysql的事务隔离
2、加锁
伪代码如下:
START TRANSACTION;
$data = select num from test where id=1 for update;
update test set num = $data['num']+1 where id=1;
COMMIT;
解释:
mysql的select属于快照读,加上for update后读取的数据属于当前读,从而解决mysql update的并发控制