鍍金池/ 問(wèn)答/Java  數(shù)據(jù)庫(kù)  網(wǎng)絡(luò)安全/ Spring boot使用Jpa操作數(shù)據(jù)庫(kù)時(shí),如何實(shí)現(xiàn)行級(jí)鎖?

Spring boot使用Jpa操作數(shù)據(jù)庫(kù)時(shí),如何實(shí)現(xiàn)行級(jí)鎖?

·Spring boot 使用 jpa 操作 MySQL InnoDB;
·比如說(shuō):

有個(gè)數(shù)據(jù)庫(kù)表products,來(lái)管理所有產(chǎn)品的庫(kù)存;
字段id為編號(hào),是主鍵;
字段quantity是數(shù)量;
業(yè)務(wù)邏輯上會(huì)有產(chǎn)品出庫(kù)和入庫(kù)的情況,有一定的并發(fā)性,所以想使用行級(jí)鎖;
然后,原本id=3的產(chǎn)品數(shù)量為2,我要出庫(kù)1個(gè),要修改庫(kù)存為1,操作如下:

·我看到網(wǎng)上的sql語(yǔ)句是:

SET AUTOCOMMIT=0;//關(guān)閉自動(dòng)提交
BEGIN WORK;//開(kāi)始事物
SELECT quantity FROM products WHERE id=3 FOR UPDATE;
UPDATE products SET quantity = '1' WHERE id=3;
COMMIT WORK;//提交事物

·我在使用Jpa時(shí),如果實(shí)現(xiàn)這些?我上網(wǎng)搜索,查到了下面的實(shí)現(xiàn):

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

問(wèn)題1.在實(shí)際使用時(shí)怎么用?
我的想法:我先調(diào)用findById(3),然后修改quantity后,save(products),是這樣么?這樣事物就完整提交了?
問(wèn)題2.如果我調(diào)用findById(3)后,不調(diào)用save(products),會(huì)怎么樣?
問(wèn)題3.如果跟我在“問(wèn)題1”里的想法不一樣,應(yīng)該是怎么弄?

回答
編輯回答
還吻

手寫(xiě)語(yǔ)句+注解,mysql Innodb 自己會(huì)加行級(jí)鎖,保證下面的語(yǔ)句線程安全,當(dāng)然 前提是你的 id 有索引


@Modifying
@Query("update products sc set quantity = quantity -1 where sc.id = ?")
public void UpdateById(@Param(value = "ids") String id);
2018年2月26日 04:44
編輯回答
孤客

這種情況下用樂(lè)觀鎖的方式會(huì)比較好

對(duì)應(yīng)的sql

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

先把之前的庫(kù)存取出來(lái), 如果之時(shí)沒(méi)有別人修改,會(huì)修改成功,否則可以重試,直到庫(kù)存不再大于購(gòu)買(mǎi)量為止。

2017年12月10日 08:04