JDBC 连接 与 事务
String url = "jdbc:mysql://localhost:3310/test?useSSL=false";
String user = "root";
String password = "root";
Connection conn = null;
PreparedStatement stmt = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
// 事务 1. 开启事务处理
conn.setAutoCommit(false);
String sql = "UPDATE test SET count=? WHERE id = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, 111);
stmt.setInt(2, 1);
stmt.executeUpdate();
// 事务 2. 模拟中途可能出现故障
Thread.sleep(10000);
sql = "UPDATE test SET count=? WHERE id = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, 222);
stmt.setInt(2, 2);
stmt.executeUpdate();
// 事务 3. 提交事务
conn.commit();
} catch (Exception e) {
// 事务 4. 事务回滚
conn.rollback();
} finnally {
if (stmt != null) {
try {
stmt.close();
}
}
if (conn != null) {
try {
conn.close();
}
}
}
事务隔离级别
1. 脏读: 一个事务读取到另一个事务未提交的数据, 即 提交前后读取的数据都一样. 提交之前认为提交了
2. 不可重复读: 事务提交之前的数据 与提交之后的数据 读取的不一样
3. 虚读(幻读): 读取到了 别的事务插入的数据
4. 虚读不一定发生
count = 1 id = 1
count = 1 id = 2
update(count = 11 where id = 1)
sleep(10000)
update(count = 11 where id = 2)
commit();
query(count where id = 1)
// 脏读
// count = 11 前 commit() 后 11
// 不可重复读
// count = 1 前 commit() 后 11
事务隔离示例
假设数据库有这么个数据
id | count | other |
---|---|---|
1 | 100 | - |
2 | 200 | - |
执行 上面的事务代码
// 注意
// 事务 2. 模拟中途可能出现故障
Thread.sleep(10000);
其他连接过来读取这里的数据
String sql = "SELECT id, count FROM test WHERE id = ?";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1, 1);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt("id"));
System.out.println(rs.getInt("count"));
}
只有等 sleep(1000)
之后的 conn.commit()
才会读取到修改后的值