mysql层的锁机制,常用的就是乐观锁,用于判断并发修改问题,常在update语句中体现。
乐观锁
mysql的乐观锁通俗点理解就是在查询时取出数据的唯一标识,在修改操作时用这个唯一标识去判断该数据有没有被其他人修改过。常见的我们会在表设计时候冗余一个version字段,表示版本号的概念,在select时把这个字段也一并查询出来,update时的where条件加上这个version判断。例如在 "高并发秒杀功能架构设计" 一文中说到的扣减库存场景:
如果update时的version和select出来的version不相等,则update成功返回的记录数为0,以此判断是否存在并发问题。乐观锁在我们的实际项目中用的较多,实际上每个涉及到mysql的update操作,你都得仔细考虑是否存在并发修改问题。如果乐观锁判断存在并发修改,这时候就需要程序手动返回错误码了。
悲观锁
悲观锁,天性悲观,认为所有SQL都是它的竞争对手,所以在它操作数据库的时候就把表给锁住了(可能是行级锁,也可能是表级锁)。通俗的说就是在select数据时把符合条件的数据给锁上,谁也不能动,待该SQL事务提交后释放锁,其它SQL方可执行,悲观锁依赖于INNODB存储引擎的mysql,而乐观锁不依赖。
基本步骤为:
1、set autocommit = 0设置事务不允许自动提交;
2、begin 开启事务;
3、会话1进行select ……for update,"for update"是关键字;
3、会话2进行update会一直阻塞,直至会话1手动提交事务;
由上可知,使用了悲观锁后,如果某个SQL执行的时间过长会执行了大事务,则会一直锁着,写的tps严重降低,这点可以类比java里的synchronized关键字,synchronized使用的也是悲观锁机制。还有一个是悲观锁的锁对象,建议where条件使用id或者索引,这样便是行级锁,不然表级锁更加降低mysql的tps。
引申阅读: Mysql二进制日志详解:https://blog.csdn.net/fanrenxiang/article/details/70193636