本文共 1398 字,大约阅读时间需要 4 分钟。
乐观的认为操作不会导致冲突,在操作数据时,并不进行任何其他特殊处理(也就是不加锁),
而是在进行更新时,再去判断是否有冲突。 MySQL数据库不支持乐观锁,需要开发者自己实现。
给表添加一个版本号或者时间戳(基于version、基于timestamp字段),每次操作后,将记录的版本号加1。实际的做法为,先查询出来那条记录,获取version字段,如果要对那条记录进行更新操作,则先判断此时version的值是否与刚才查出来的version的值相等,如果相等,则说明这段期间,没有其他程序对其进行操作,则可以进行更新操作,并将version字段的值加1;如果更新时发现此刻version值与刚才取出来的version的值不相等,则说明这段期间已经有其他程序对其进行更新操作,则不进行更新操作。
select (status, version) from tbl_goods where id=#{id};
update tbl_goods set status=2, version=version+1 where id=#{id} and version=#{version};
4、判断update影响的行数,如果为0则本次更新失败,如果为1,则更新成功。
悲观锁在操作数据时,认为此操作会出现数据冲突,所以在每次操作时都要通过获取锁来对数据进行操作。悲观锁是由数据库自己实现的。
select for update或者lock in share mode,必须包裹
在事务中才生效。
select status from tbl_goods where id=1 for update; // 悲观锁 (id字段未普通索引,只锁定该行,不是索引就会锁全表)
update tbl_goods set status=2;
对于update、delete和insert语句,InnoDB会自动给涉及数据添加排他锁。对于普通select语句,innodb不会加任何锁。
如上update的更新操作会加自动加排他锁,因此,不需要而外再去处理其他操作,直接使用如下语句:
update tbl_goods set count=count+1 where id=1; // 利用mysql计数器实现计数操作 select count from tbl_goods where id=1;
update tbl_goods set count=#{count} where id=1;
select count from tbl_goods where id=1 for update;
count = count +1; // 其他操作
update tbl_goods set count = #{count} where id=1;
转载地址:http://qgomi.baihongyu.com/