Java中如何通过if语句实现单机环境下的乐观锁版本号校验流程?
- 内容介绍
- 文章标签
- 相关推荐
本文共计731个文字,预计阅读时间需要3分钟。
相关专题
在单机环境下,乐观锁通常通过版本号(version)字段实现,核心思路是:读取数据时记录当前版本号,更新前检查数据库中该记录的版本号是否仍与读取时一致,一致则更新并递增版本号,否则拒绝更新。java 中用 if 判定即可完成这一校验逻辑,无需依赖数据库的 cas 语句或分布式锁。
读取数据并缓存版本号
从数据库(如使用 JDBC 或 MyBatis)查询实体时,必须同时获取主键和 version 字段。例如:
// 假设 User 实体包含 id、name、version 字段
User user = userMapper.selectById(userId); // 返回对象含 version 值
int originalVersion = user.getVersion(); // 保存原始版本号,供后续校验
更新前用 if 校验版本一致性
执行更新操作前,先查一次数据库当前版本号(或在更新 SQL 中直接 WHERE version = ?),再用 if 判断是否匹配。常见两种写法:
-
方式一(推荐):在 UPDATE SQL 中嵌入版本校验
SQL 写成UPDATE user SET name = ?, version = version + 1 WHERE id = ? AND version = ?,然后用 Java 判断updateCount == 1是否成立。 -
方式二(显式校验):先 SELECT 再 if 判断
User current = userMapper.selectById(userId);if (current.getVersion() != originalVersion) { throw new OptimisticLockException("版本已变更"); }
再执行更新(此时需确保两次查询间无并发修改,单机场景下风险较低,但仍建议用方式一)。
更新成功后同步本地状态
若更新生效(if (rowsAffected == 1) 成立),说明校验通过,应立即更新本地对象的 version 值,保持内存与数据库一致:
user.setVersion(user.getVersion() + 1);- 避免后续基于旧 version 的误判
- 尤其在连续多次编辑场景中,这步能防止“ABA”类逻辑错误
处理校验失败的典型响应
当 if 判定版本不一致时,不应静默覆盖,而应明确反馈:
立即学习“Java免费学习笔记(深入)”;
- 抛出自定义异常(如
OptimisticLockException),由上层捕获并提示“数据已被他人修改,请刷新后重试” - 或返回特定结果码(如
Result.failure(409, "版本冲突")) - 不建议自动重试(单机下意义有限),除非业务明确要求“强最终一致”且可接受覆盖风险
本文共计731个文字,预计阅读时间需要3分钟。
相关专题
在单机环境下,乐观锁通常通过版本号(version)字段实现,核心思路是:读取数据时记录当前版本号,更新前检查数据库中该记录的版本号是否仍与读取时一致,一致则更新并递增版本号,否则拒绝更新。java 中用 if 判定即可完成这一校验逻辑,无需依赖数据库的 cas 语句或分布式锁。
读取数据并缓存版本号
从数据库(如使用 JDBC 或 MyBatis)查询实体时,必须同时获取主键和 version 字段。例如:
// 假设 User 实体包含 id、name、version 字段
User user = userMapper.selectById(userId); // 返回对象含 version 值
int originalVersion = user.getVersion(); // 保存原始版本号,供后续校验
更新前用 if 校验版本一致性
执行更新操作前,先查一次数据库当前版本号(或在更新 SQL 中直接 WHERE version = ?),再用 if 判断是否匹配。常见两种写法:
-
方式一(推荐):在 UPDATE SQL 中嵌入版本校验
SQL 写成UPDATE user SET name = ?, version = version + 1 WHERE id = ? AND version = ?,然后用 Java 判断updateCount == 1是否成立。 -
方式二(显式校验):先 SELECT 再 if 判断
User current = userMapper.selectById(userId);if (current.getVersion() != originalVersion) { throw new OptimisticLockException("版本已变更"); }
再执行更新(此时需确保两次查询间无并发修改,单机场景下风险较低,但仍建议用方式一)。
更新成功后同步本地状态
若更新生效(if (rowsAffected == 1) 成立),说明校验通过,应立即更新本地对象的 version 值,保持内存与数据库一致:
user.setVersion(user.getVersion() + 1);- 避免后续基于旧 version 的误判
- 尤其在连续多次编辑场景中,这步能防止“ABA”类逻辑错误
处理校验失败的典型响应
当 if 判定版本不一致时,不应静默覆盖,而应明确反馈:
立即学习“Java免费学习笔记(深入)”;
- 抛出自定义异常(如
OptimisticLockException),由上层捕获并提示“数据已被他人修改,请刷新后重试” - 或返回特定结果码(如
Result.failure(409, "版本冲突")) - 不建议自动重试(单机下意义有限),除非业务明确要求“强最终一致”且可接受覆盖风险

