数据库中user表
id | role |
---|---|
1 | 11 |
伪代码,使用原始的JDBC
public void unautoCommitUpdate() {
Connection updateConn = newConnection(); // 更新用的连接
Connection newConn = newConnection(); // 再创建一个连接
/*
这两个connection是不同的对象,都设置成不自动提交
Connection默认的事务级别是 TRANSACTION_REPEATABLE_READ(不可以脏读和不可重复读;可以虚读,虚读就是insert了一条符合条件的记录可以查询到)
*/
updateConn.setAutoCommit(false);
newConn.setAutoCommit(false);
User u = new User();
u.setId(1);
u.setRole(22); // 修改role为22
String updateSql = "UPDATE USER SET role = ? WHERE id = ?";
PreparedStatement updatePs = updateConn.prepareStatement(updateSql);
updatePs.setInt(1, u.getRole());
updatePs.setInt(2, u.getId());
updatePs.executeUpdate();
// update不提交查询
getById(u.getId(), updateConn); // role: 22, 自己修改的哪怕不提交也对自己有效
getById(u.getId(), newConn); // role: 11, 不提交对另一个无效
updateConn.commit();
// update提交后查询
getById(u.getId(), updateConn); // role: 22, 提交后对自己依然有效
getById(u.getId(), newConn); // role: 11, 提交后对另一个也无效, 因为事务级别是不可以不可重复读,也就是可以重复读而且重复读到的是第一次读到的值(说明每个connection都有缓存,只要这个connection不commit,他下次查还是查到之前的值,哪怕另一个事务修改了这个值也对他没影响)
newConn.commit();
// 另一个connection提交后查询
getById(u.getId(), updateConn); // role: 22
getById(u.getId(), newConn); // role: 22, 只有这个事务提交后再查询才能查到最新值(缓存失效,可以理解为commit还有清除缓存的功能)
}
public User getById(Integer id, Connection conn) throws SQLException {
String sql = "SELECT * FROM user WHERE id = "+ id;
PreparedStatement psQuery = conn.prepareStatement(sql);
// psQuery.setInt(1, id);
ResultSet rs = psQuery.executeQuery(sql);
User rst = null;
while (rs.next()) {
rst = USER_MAPPER.mapRow(rs, rs.getRow());
}
rs.close();
psQuery.close();
return rst;
}