乐观锁是一种无锁并发控制策略,核心思想是“乐观地认为并发冲突不常发生”,只在数据提交时检测冲突。Version 机制是其最常用实现方式,适用于读多写少、冲突频率较低的场景(如账户余额更新、库存扣减、状态变更)。
一、 核心原理与流程
-
核心思想:
-
读取数据时,不锁定记录。
-
更新数据时,检查自读取后版本号(或时间戳等)是否被其他事务修改。
-
如果版本号一致,则更新数据并递增版本号。
-
如果版本号不一致,则认为发生冲突,放弃本次更新(通常通过重试或业务逻辑处理)。
-
-
核心组件:
-
版本字段 (
version): 表中增加一个整型字段(或时间戳字段update_time),每次成功更新记录时递增(或更新为当前时间)。 -
读取 (
SELECT): 读取数据时,同时获取当前version值(old_version)。 -
更新 (
UPDATE): 更新时,在WHERE条件中包含version = old_version,并SET version = new_version。
-
二、 关键实现细节与变种
-
版本字段类型选择:
-
整型 (
INT/BIGINT): 最常用。递增简单高效 (version = version + 1)。 -
时间戳 (
TIMESTAMP/DATETIME): 更新时间精确到毫秒/微秒。更新时SET update_time = NOW(3)(MySQL 5.6.4+ 支持毫秒)。冲突检测粒度更细,但需确保数据库服务器时间同步,且NOW()函数精度足够。 -
哈希/校验和: 对整行数据计算哈希值作为版本。能检测任意字段的修改,但计算开销较大,且
WHERE条件可能复杂。较少用。
-
-
UPDATE语句的原子性:-
关键保障:
UPDATE ... WHERE id=xxx AND version=old_version是原子的。数据库保证在满足条件的记录上执行更新(包括version = version + 1)是不可分割的操作。 -
并发安全: 即使多个事务同时执行此
UPDATE,也只有一个能成功修改version=old_version的那条记录(如果存在)。其他事务会因条件不匹配而更新 0 行。
-
-
冲突检测 (
affected_rows):-
affected_rows == 0的含义:-
乐观锁冲突 (最常见): 其他事务已成功更新了该记录,导致
version值改变,不再等于old_version。 -
记录已被删除:
WHERE id=123 AND version=5的记录不存在了。 -
业务数据不满足条件: 如果
WHERE
-
-

最低0.47元/天 解锁文章
1249

被折叠的 条评论
为什么被折叠?



