我想了解ACID隔离原理。我已经编好了这部分代码。
ExecutorService executorService = Executors.newSingleThreadExecutor();
Runnable t2 = () -> {
System.out.println("Thread: " + Thread.currentThread().getName());
Connection connection;
try {
connection = this.iDatabaseConnector.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM mssmbank.mssmbank.bankaccounts WHERE id = ?");
preparedStatement.setInt(1, 490);
ResultSet resultSet = preparedStatement.executeQuery();
resultSet.next();
System.out.println("Result: " + resultSet.getDouble("BALANCE"));
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
};
Runnable t1 = () -> {
System.out.println("Thread: " + Thread.currentThread().getName());
Connection connection;
try {
connection = this.iDatabaseConnector.getConnection();
connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE mssmbank.mssmbank.bankaccounts " + "SET balance = ? WHERE id = ?");
preparedStatement.setDouble(1, (new Random()).nextInt(1000));
preparedStatement.setInt(2, 490);
preparedStatement.executeUpdate();
ExecutorService executorService1 = Executors.newSingleThreadExecutor();
executorService1.execute(t2);
Thread.sleep(3_000);
connection.commit();
connection.close();
executorService1.shutdown();
executorService1.awaitTermination(20, TimeUnit.SECONDS);
} catch (SQLException | InterruptedException e) {
e.printStackTrace();
}
};
executorService.execute(t1);
executorService.shutdown();
executorService.awaitTermination(20, TimeUnit.SECONDS);
有两个线程 t1 和 t2. t1 应该是 更新 数据库中的银行账户行,以及 t2 应该是 阅读 其平衡。
情况是这样的。t1 启动,打开一个连接,进行更新和 不犯. 它引发了 t2 和 睡觉 3秒。
t2 启动,打开连接,读取余额并打印出来(基本上是老的,因为 t1 还没有提交)然后关闭连接。
然后 t1 饰演者 承诺 更新和程序结束。
我希望发生的是 t2 受阻 t1 已完成承诺,因为 t2 正在访问同一银行账户行(t1 应该锁定该行进行更新)。) 因此。t2 应该打印的是490号银行账户的最新余额,而不是之前的。
为什么不 t1 为什么不 t2 被屏蔽了?需要注意的是 隔离度 设置为 TRANSACTION_READ_COMMITTED
.
t2中的select语句没有被阻塞,因为它只是试图读而不是写。如果你试图执行更新(或选择...进行更新),那么如果你的超时设置为等待一段时间后才放弃,它可能会被阻塞。你没有提到你使用的是哪个数据库,但这里有一些关于Postgres如何处理锁定的漂亮文档。https:/www.postgresql.orgdocscurrentexplicit-locking.html