在项目的开发中,我们肯定会用到锁机制来解决并发的问题, 其中被大家广为应用的有:
- synchronized
- java.util.concurrent.locks.ReentrantReadWriteLock
- java.util.concurrent.locks.Lock 系列
- Mysql 的乐观锁,悲观锁
- 等等
下面,我将介绍的锁是:【悲观锁 select * for update】
1. 使用
上图是我所使用的列子, 首先一个方法中有一个查询语句findSequence, 和一个更新语句updateSequence。
其中在查询语句中使用悲观锁:
SELECT * FROM ke_sequence WHERE id = #{id} FOR UPDATE
而更新语句只是平常的update语句:
UPDATE ke_sequence SET sequence = sequence +1 WHERE id = #{id} AND sequence= #{sequence}
2. 注意事项
- 该方法必须在事物中,可以使用@Transactional;
- 在select for update查询中必须使用id主键作为条件,否则使用不当,容易造成全表被锁住。
- 如果有多个方法都使用了悲观锁,且都是对相同的几个表进行加锁,必须注意加锁的顺序问题,否则容易造成死锁。
3. 什么时候释放锁?
- 该语句的事务被commit语句或rollback