-
create table t(
-
id int primary key auto_increment,
-
quantity int
-
) engine=innodb;
-
- insert into t values(1,10),(2,20),(3,25),(4,40);
环境设置
set @@session.tx_isolation='REPEATABLE-READ';
set @@session.autocommit=false;
线程1,查询id为1的剩余数量,经过一些业务操作(模拟),将库存增加100
同时,线程2,查询id为1的剩余数量,也经过一些业务操作,将库存增加200
可以看到,线程二的更新丢失了.
解决这个问题有两种方式,悲观锁和乐观锁
1.悲观锁(select for update)
2.乐观锁
增加一个版本字段version(整形或者时间戳类型)
解决这个问题有两种方式,悲观锁和乐观锁
1.悲观锁(select for update)
2.乐观锁
增加一个版本字段version(整形或者时间戳类型)
-
create table t(
-
id int primary key auto_increment,
-
quantity int,
-
version int default 0
-
) engine=innodb;
-
- insert into t(id,quantity) values(1,10),(2,20),(3,25),(4,40);
还有一种丢失更新.
假设有一个b/s库存系统(注意是b/s系统)
商品库存为5
此时管理员A打开页面,增加了5个库存,页面显示库存为10,但是管理员A没有提交(没有点击保存按钮),然后他喝茶去了。
一会儿管理员B,打开另一个电脑的页面,显示商品的库存为5(因为A没有提交,所以B看到的还是5),他增加了100个库存,点击保存。此时,商品库存为105.
管理员A喝茶归来,发现刚才的工作竟然没有保存,点击保存按钮.这时系统直接将10写入数据库。
那么,管理员B的更新丢失了.
解决这种问题,不能使用悲观锁,只能使用乐观锁.将数据的版本信息写入前台界面的一个隐藏域或者存入session,在更新的时候,用于判断数据是否已经被修改过.