MySQL 锁
悲观锁
对数据的处理持悲观态度,认为会发生并发冲突,获取或修改数据时,其他人会修改数据,所以在整个数据处理过程中,需要将数据锁定;
悲观锁依靠数据库提供的锁机制实现,如排它锁 select ... for update
使用悲观锁时需要关闭mysql自动提交功能 set autocommit = 0;
事务提交时会释放 事务过程中的锁;
悲观锁在并发控制上采取的是先上锁,然后再处理数据的保守策略,虽然保证了数据处理的安全性,但也降低了执行效率。
乐观锁
就是对数据的处理持乐观态度,乐观的任务数据一般情况下不会发生冲突,只有提交数据更新时,才会对数据是否冲突进行检测;
如果发生冲突,则返回错误信息给用户,让用户自己决定如何操作。
乐观锁的实现不依靠数据库提供的锁机制,需要我们自己实现,实现的方式一般是记录数据版本,一种是通过版本号,一种是通过时间戳;
给表加一个版本号或时间戳字段,读取数据时,将版本号一同读出,数据更新时,将版本号加1;
当我们提交数据更新时,判断当前版本号是否和之前读取的版本号相等,若相等则予以更新,否则认为数据过期,拒绝更新,让用户重新操作;
乐观锁是基于程序实现的,所以不存在死锁问题,适用于读多的应用场景,如果经常发生冲突,上层应用不断的让用户进行重新操作,这反而降低了性能,这种情况下悲观锁就更加适合
共享锁
又称为读锁
当一行数据开启共享锁时,其他事务可以开启共享锁,不可以开启排他锁
关闭自动提交 set autocommit = 0; 或使用 begin 开启事务
select ... lock in share mode; //设置共享锁
select @@autocommit; 查看自动提交状态
排它锁
又称写锁 当一行数据开启排它锁时,其他事务不能开启排它锁、共享锁
关闭自动提交 set autocommit = 0;
select ... for update //排他锁
参考: https://blog.csdn.net/diaobatian/article/details/90603887
https://zhuanlan.zhihu.com/p/46502248