1.MySQL悲观锁
悲观锁:顾名思义,对待过来的请求持比较悲观的态度,在处理请求的整个过程中,将数据锁定,不允许其他进程/线程 修改
set autocommit=0;
begin;
select * from table where id = xx for update; //互斥锁 //InnoDB 必须明确索引字段的值(查询需走索引),否则会将整个表的数据都加锁
// select * from table where id = xx lock in share mode; // 共享锁,容易造成死锁,谨慎使用
......
// 对数据进行操作
......
commit;
当session1执行完 select * from table where field = xx for update; (field需要是索引字段) 的时候 就将那一行的数据锁定了,此时 session2 再来执行 for update 或者 修改此条数据的操作的时候就会被阻塞
注:MySQL 悲观锁 虽然数据可以保证绝对正确,但是并发效率极低,一般不使用
数据库有隐藏的创建版本和删除版本的字段,每次开始事务的时候,事务版本号都会自增
新增数据的时候,在对应的创建版本号的地方填上 当前事务的版本号
更新数据的时候,将要更新的数据行的删除版本号填上当前事务的版本号,然后插入一条新数据,创建版本号 填上 当前事务的版本号
删除数据的时候,将要删除的数据行的删除版本号填上当前事务的版本号
查询数据的时候,查询 删除版本号大于当前事务的版本号 或 创建版本号小于等于当前事务的版本号且删除版本号为空
2.在where 条件中进行限制
// 在秒杀场景中的使用
1. 将库存字段设置为 unsigned int 类型,库存一直减,减到负数就直接报错,应用程序捕获这个错误进行处理这种方式依赖数据库抛异常,算是数据库设计的一种技巧,不算乐观锁
2. 更新库存的时候,直接 update table set remain_amount = remain_amount - num where id = xx and remain_amount >= num // num 是一个
3. 结合 1,2
3.Redis 分布式锁 参考 石杉的架构笔记--Redis分布式锁的实现原理
1.原理大概是这样的(Redis可能是一个集群,这里就当做是单机的场景,集群的话 加锁只给master节点加锁):
释放锁的时候,直接将 resource_str key 删除即可
注:1. resource_str代表资源key client_str 代表客户端字符串或者是session字符串
2. 上述情况如果 time过长,可以直接返回 超时
3.Redis 分布式锁的改进
4.Redis 分布式锁的改进
注:1. 本文根据自己的理解所写,如有不对的地方请及时反馈。
2. 如需转载,请注明出处:https://cloud.tencent.com/developer/article/1614808
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有