跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

什么是数据库的悲观锁和乐观锁_在MyBatis中使用for update与版本号方案落地

MyBatis 中 SELECT ... FOR UPDATE 未锁住行,根本原因是事务未开启或隔离级别不支持;必须配合 @Transactional、InnoDB 引擎及合适隔离级别,并确保 SQL 正确书写且条件命中索引。 MyBatis 中
SELECT ... FOR UPDATE
为什么没锁住行? 根本原因通常是事务未开启或隔离级别不支持。MyBatis 本身不控制事务边界,
FOR UPDATE
只在数据库事务内生效,且依赖存储引擎(如 InnoDB)和隔离级别(推荐
REPEATABLE READ
或
READ COMMITTED
)。 Spring 项目中必须确保方法被
@Transactional
注解包裹,且传播行为不是
SUPPORTS
或
NOT_SUPPORTED
MySQL 5.7+ 默认隔离级别是
REPEATABLE READ
,但若应用显式设为
READ UNCOMMITTED
,
FOR UPDATE
会失效 MyBatis 的
标签(
selectForUpdate
/
selectNormal
) 切勿在
循环中对多 ID 加锁:
SELECT ... WHERE id IN (...) FOR UPDATE
会锁住所有匹配行,但若部分 ID 不存在,InnoDB 仍可能锁住间隙,引发意外阻塞 MyBatis 3.4+ 支持
useGeneratedKeys
和
FOR UPDATE
共存,但 Oracle 不支持,跨库时别默认套用 真正难的从来不是写对一行
FOR UPDATE
或加个
version
字段,而是想清楚这笔更新背后有没有其他服务也在改同一行、事务里混没混业务查询、下游会不会因锁等待超时而降级失败——这些没法靠框架自动兜底。

相关文章