Mysql 只有Innodb支持行鎖
使用行鎖需要 事務支持
首先打開兩個 mysql-client
分別執行
- client1
select * from my_entity1 for update;
- client2
select * from my_entity1 for update;
發現行鎖無效,說明需要事務支持
- client1
start transaction;
select * from my_entity1 for update;
- client2
select * from my_entity1 for update;
這個時候 client2 阻塞等待鎖
此時給client1 輸入 commit;
client2獲得鎖並且獲取結果
如果client2 不加行鎖也是不會被阻塞的
除此之外 forupdate還有其他方法
select * from t for update 會等待行鎖釋放之后,返回查詢結果。
select * from t for update nowait 不等待行鎖釋放,提示鎖沖突,不返回結果
select * from t for update wait 5 等待5秒,若行鎖仍未釋放,則提示鎖沖突,不返回結果
select * from t for update skip locked 查詢返回查詢結果,但忽略有行鎖的記錄
Spring jpa 行鎖
- 對調用的service 加 @Transaction注解
- 使用 @Query 原生sql注解
@Transactional
public void updateLockTester()
public interface Entity2Dao extends JpaRepository<MyEntity2, Long> {
List<MyEntity2> findAllByTagEquals(Integer tag);
@Query(value = "select * from my_entity2 where tag = :tag for update", nativeQuery = true)
List<MyEntity2> findAllByTag2Equals(@Param("tag") Integer tag);
}
不能太過於依賴行鎖,更建議使用分布式鎖提高效率