Я пытаюсь понять принцип изоляции 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);
Есть 2 потока, t1 и t2 . t1 должен обновить строку банковского счета в базе данных, а t2 должен прочитать свой баланс.
Вот сценарий: t1 запустить, открыть соединение, сделать обновление и не зафиксировать . Он запускает t2 и спит в течение 3 секунд.
t2 запускает, открывает соединение, считывает баланс и печатает его (в основном старый один, потому что t1 еще не зафиксирован), затем закройте соединение.
Затем t1 завершится к , совершив обновление, и программа завершится.
Я ожидаю, что t2 будет заблокирован до тех пор, пока t1 не завершит фиксацию, поскольку t2 получает доступ к тому же банковскому счету. строка ( t1 должна была заблокировать строку для обновления). Поэтому t2 должен был печатать обновленный баланс банковского счета # 490, а не предыдущий.
Почему t1 не блокирует строку? почему t2 не блокируется? Обратите внимание, что Уровень изоляции установлен на TRANSACTION_READ_COMMITTED
.