Spring boot使用Jpa操作数据库时,如何实现行级锁?

Ranger
  • 47

·Spring boot 使用 jpa 操作 MySQL InnoDB;
·比如说:

有个数据库表products,来管理所有产品的库存;
字段id为编号,是主键;
字段quantity是数量;
业务逻辑上会有产品出库和入库的情况,有一定的并发性,所以想使用行级锁;
然后,原本id=3的产品数量为2,我要出库1个,要修改库存为1,操作如下:

·我看到网上的sql语句是:

SET AUTOCOMMIT=0;//关闭自动提交
BEGIN WORK;//开始事物
SELECT quantity FROM products WHERE id=3 FOR UPDATE;
UPDATE products SET quantity = '1' WHERE id=3;
COMMIT WORK;//提交事物

·我在使用Jpa时,如果实现这些?我上网搜索,查到了下面的实现:

@Lock(LockModeType.PESSIMISTIC_WRITE)  
public products findById(int id);

问题1.在实际使用时怎么用?
我的想法:我先调用findById(3),然后修改quantity后,save(products),是这样么?这样事物就完整提交了?
问题2.如果我调用findById(3)后,不调用save(products),会怎么样?
问题3.如果跟我在“问题1”里的想法不一样,应该是怎么弄?

回复
阅读 6k
2 个回答
Yujiaao
  • 12.5k

这种情况下用乐观锁的方式会比较好

对应的sql

 update products  set quantity = quantity - :bye_count
  where id = :id and quantity=:old_value and quantity > :bye_count
 

先把之前的库存取出来, 如果之时没有别人修改,会修改成功,否则可以重试,直到库存不再大于购买量为止。

手写语句+注解,mysql Innodb 自己会加行级锁,保证下面的语句线程安全,当然 前提是你的 id 有索引


@Modifying
@Query("update products sc set quantity = quantity -1 where sc.id = ?")
public void UpdateById(@Param(value = "ids") String id);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏