两种丢失更新

假设t表是库存表,quantity表示剩余数量
  1. create table t(
  2.     id int primary key auto_increment,
  3.     quantity int
  4. ) engine=innodb;

  5. 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. create table t(
  2.     id int primary key auto_increment,
  3.     quantity int,
  4.     version int default 0
  5. ) engine=innodb;

  6. 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,在更新的时候,用于判断数据是否已经被修改过.
请使用浏览器的分享功能分享到微信等