MySQL数据库提供的悲观锁和乐观锁

注:要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。

我们可以使用命令设置MySQL为非autocommit模式:

set autocommit=0;

select status from t_goods where id=1 for update;(关键点select ..... for update)
此时id为1的数据就被锁定了。

注:需要注意的是,在事务中,只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 同一笔数据时会等待其它事务结束后才执行,一般SELECT ... 则不受此影响。拿上面的实例来说,当我执行select status from t_goods where id=1 for update;后。我在另外的事务中如果再次执行select status from t_goods where id=1 for update;则第二个事务会一直等待第一个事务的提交,此时第二个查询处于阻塞的状态,但是如果我是在第二个事务中执行select status from t_goods where id=1;则能正常查询出数据,不会受第一个事务的影响。

补充mysql select ... for update 的行锁定 和表锁定

  1. 明确指定主键,并且有此数据,row lock select * from t_goods where id=1 for update;
  2. 明确指定主键,若查无此数据,无lock select * from t_goods where id=10000 for update;
  3. 无主键,table lock select * from t_goods where name='道具' for update;
  4. 主键不明确,table lock select * from t_goods where id>0 for update;
  5. 明确指定索引,并且有此数据,row lock select * from t_goods where status=1 for update; (status 为索引字段)
  6. 明确指定索引,若查无此数据,无lock
乐观锁介绍

字段类型使用时间戳(timestamp), 也是在更新提交的时候检查当前数据库中数据的时间戳和自己更新前取到的时间戳进行对比,如果一致则OK,否则就是版本冲突。

1.查询出商品信息
select (status,version) from t_goods where id=#{id}
2.根据商品信息生成订单
3.修改商品status为2
update t_goods 
set status=2,version=version+1
where id=#{id} and version=#{version};

你可能感兴趣的:(MySQL数据库提供的悲观锁和乐观锁)