用mysql实现一段乐观锁代码
乐观锁是一种基于版本号的并发控制机制,它假设并发访问的数据冲突的概率很小,因此不会阻塞线程,而是在更新数据时检查数据版本号是否一致,如果一致则更新数据,如果不一致则放弃更新并抛出异常或者重试。
在MySQL中,可以使用版本号字段实现乐观锁。假设我们有一张user表,其中包含id、name和version三个字段。现在要更新id为1的用户的name字段,可以如下实现:
START TRANSACTION;
SELECT version FROM user WHERE id = 1;
UPDATE user SET name = 'new_name', version = version + 1 WHERE id = 1 AND version = ?;
COMMIT;
其中,第一条SELECT语句获取当前用户的版本号,第二条UPDATE语句更新用户的name字段,并将版本号加1。如果UPDATE语句受影响的行数为0,说明版本号不匹配,更新失败,可以抛出异常或者重试。如果UPDATE语句受影响的行数为1,说明更新成功。
完整的乐观锁示例代码如下:
public void updateUser(String name, long id) throws SQLException {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = getConnection();
conn.setAutoCommit(false);
// 获取当前用户的版本号
pstmt = conn.prepareStatement("SELECT version FROM user WHERE id = ?");
pstmt.setLong(1, id);
rs = pstmt.executeQuery();
if (rs.next()) {
long version = rs.getLong("version");
// 更新用户的name字段,并将版本号加1
pstmt = conn.prepareStatement("UPDATE user SET name = ?, version = ? WHERE id = ? AND version = ?");
pstmt.setString(1, name);
pstmt.setLong(2, version + 1);
pstmt.setLong(3, id);
pstmt.setLong(4, version);
int rows = pstmt.executeUpdate();
if (rows == 1) {
// 更新成功,提交事务
conn.commit();
} else {
// 更新失败,回滚事务
conn.rollback();
throw new SQLException("Update failed due to version mismatch.");
}
} else {
throw new SQLException("User not found.");
}
} catch (SQLException e) {
if (conn != null) {
conn.rollback();
}
throw e;
} finally {
closeResources(conn, pstmt, rs);
}
}
原文地址: https://www.cveoy.top/t/topic/s9w 著作权归作者所有。请勿转载和采集!