Mysql 锁的使用
程序员文章站
2022-06-02 13:20:01
...
乐观锁
- Version版本(或者Timestamp)(例如:mysql中mvcc多版本并发控制)
乐观锁在使用的时候, 不一定在同一事务中, 只是检测version字段更新时是否和读取时值保持一致, 若一致则更新, 否则更新失败. 现在很多orm 都有实现version自动更新的功能, 使用非常方便, 也推荐使用该方式处理并发.
# 1. 更新数据库, 新增version 字段
ALTER table test add version int not null;
# 2. 设置数据库不自动提交
set autocommit = 0;
# 3. 事务1 执行
select * from test where id = 1 ;
## 可以观察事务2 version 字段为 0
# 4. 事务2 执行
select * from test where id = 1;
## 可以观察事务2 version 字段为 0
# 5. 事务1 执行
update test set age = 24 , version = version+1 where id = 1 and version = 0;
commit;
## 可以观察事务1 事务正常提交
# 6. 事务2 执行
update test set age = 24 , version = version+1 where id = 1 and version = 0;
commit;
## 可以观察事务2 正常提交, 但是受影响的行数为 0.
# 7. 设置数据库自动提交
set autocommit = 1;
commit;
悲观锁
- select …for update
for update的字段为索引或者主键的时候, 只锁住索引或者主键对应的行, 否则锁住整个表
# 1. 构造测试表
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`age` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
insert into test (name,age) values('zhao',20);
insert into test (name,age) values('xi',21);
# 2. 设置数据库不自动提交
set autocommit = 0;
# 3. 事务1 执行
select * from test where id = 1 for update;
# 4. 事务2 执行
update test set age = 22 where id = 1;
commit;
## 可以观察事务2 会一直阻塞在update 语句
# 5. 在事务1 执行 commit;
## 可以观察事务2 在事务1执行完毕后, 事务2也执行成功.
- select …lock in share mode
悲观锁也可以使用 select … lock in share mode 来实现, 不过相对select … for update 来说, 前者不会阻塞查询. 因为 前者使用 IS (意向共享锁) 锁, 后则使用 IX (意向排他锁) 锁.
# 1. 设置数据库不自动提交
set autocommit = 0;
# 2. 事务1 执行
select * from test where id = 1 lock in share mode;
# 3. 事务2 执行
select * from test where id = 1 lock in share mode;
commit;
## 可以观察事务2 并没有阻塞
# 4. 事务2 执行
update test set age = 23 where id = 1;
commit;
## 可以观察事务2 会阻塞在update语句
# 5. 事务1 执行rollback;
rollback;
## 可以观察事务2 事务正常提交
# 6. 设置数据库自动提交
set autocommit = 1;
以上 转载自:https://blog.csdn.net/wau_hua/article/details/85685754
作者:朝夕夕夕夕
Redission 分布式锁
实际工作中,不失为mysql锁的替代品。