有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准 https://blog.zysicyj.top
乐观锁(Optimistic Locking)是一种用于控制并发访问的机制,它假设并发冲突很少发生,因此在读操作时不加锁,但在写操作时会检测是否有冲突。乐观锁在应用程序层面实现,常用的方法是使用版本号或时间戳来实现。下面详细介绍如何在 MySQL 中实现乐观锁。
实现乐观锁的步骤
添加版本字段 :在需要控制并发的表中添加一个版本号字段。
读取记录时获取版本号 :读取记录时,获取当前版本号。
更新记录时检查版本号 :更新记录时,检查当前版本号是否与读取时的一致,如果一致则更新成功,否则说明数据已经被修改,更新失败。
具体实现步骤 1. 添加版本字段 假设有一个用户表 users
,我们需要在表中添加一个版本号字段 version
。
1 ALTER TABLE users ADD COLUMN version INT DEFAULT 0 ;
2. 读取记录 读取记录时,获取当前的版本号。
1 SELECT id, name, email, version FROM users WHERE id = 1 ;
3. 更新记录 更新记录时,检查版本号是否匹配,如果匹配则更新成功,并且版本号递增。如果不匹配,说明数据已经被修改,更新失败。
1 2 3 UPDATE usersSET name = 'newName' , email = 'newEmail' , version = version + 1 WHERE id = 1 AND version = 2 ;
在上面的 SQL 语句中,只有当 id
为 1 且 version
为 2 时,才会执行更新操作,否则更新操作将不会进行。
4. 检查更新结果 通过检查受影响的行数来判断更新是否成功。如果受影响的行数为 0,说明更新失败,需要处理并发冲突。
1 2 3 4 int affectedRows = jdbcTemplate.update(sql, params);if (affectedRows == 0 ) { }
示例代码 以下是一个完整的 Java 示例,演示如何使用 Spring JDBC 实现乐观锁。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;import org.springframework.dao.DataAccessException;public class UserService { private final JdbcTemplate jdbcTemplate; public UserService (JdbcTemplate jdbcTemplate) { this .jdbcTemplate = jdbcTemplate; } public User getUserById (int id) { String sql = "SELECT id, name, email, version FROM users WHERE id = ?" ; return jdbcTemplate.queryForObject(sql, new Object []{id}, userRowMapper); } public boolean updateUser (User user) { String sql = "UPDATE users SET name = ?, email = ?, version = version + 1 WHERE id = ? AND version = ?" ; int affectedRows = jdbcTemplate.update(sql, user.getName(), user.getEmail(), user.getId(), user.getVersion()); return affectedRows > 0 ; } private final RowMapper<User> userRowMapper = (rs, rowNum) -> { User user = new User (); user.setId(rs.getInt("id" )); user.setName(rs.getString("name" )); user.setEmail(rs.getString("email" )); user.setVersion(rs.getInt("version" )); return user; }; public static class User { private int id; private String name; private String email; private int version; } }
总结 通过使用版本号来实现乐观锁,可以有效地控制并发访问,防止数据被并发修改时产生冲突。乐观锁适用于并发冲突较少的场景,因为它避免了在读操作时加锁,从而提高了系统的并发性能。通过合理设计,可以在 MySQL 中高效地实现乐观锁机制。