Я устанавливаю два подключения JDBC к базе данных тестирования MySQL и использую InnoDB. Соединения начать операции в различных уровнях изоляции, и я проверить, какие изменения могут видеть, какое соединение, после чего действия:Возможно ли поведение MySQL?
public static void main(String args[]) {
final Connection con1 = DriverManager.getConnection(url, user, passwd);
con1.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
con1.setAutoCommit(false);
final Connection con2 = DriverManager.getConnection(url, user, passwd);
con2.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
con2.setAutoCommit(false);
System.out.println(countRows(con1));
System.out.println(countRows(con2));
addRow(con1);
System.out.println(countRows(con1));
System.out.println(countRows(con2));
con1.commit();
System.out.println(countRows(con1));
System.out.println(countRows(con2));
}
С этими вспомогательными методами:
public static int countRows(final Connection c) throws Exception {
final Statement s = c.createStatement();
final ResultSet rs = s.executeQuery("SELECT * FROM test;");
int count = 0;
while(rs.next()) {
count++;
}
rs.close();
s.close();
return count;
}
public static void addRow(final Connection c) throws Exception {
final Statement s = c.createStatement();
s.executeUpdate("INSERT INTO test (user, age) VALUES ('Guy', 42);");
}
Я бегу код всегда, начиная с пустой стол. Выход я получаю
0 //initially no rows for both connections
0
1 //con1 adds row
0 //con2 does not see uncommitted new row
1
0 //con1 has committed => Why isn't the new row visible?
Я ожидаю, что последнее число будет 1, потому что con1
уже совершил в это время. Почему это так? Будет ли поведение, которое я ожидаю, легальным с заданными уровнями изоляции? Насколько я понимаю, феномен чтения, который я создаю, является фантомным чтением, так что это должно быть хорошо с REPEATABLE_READ
, правильно?
Попробуйте * не * запустить 'countRows (con2)' до появления 'addRow (con1)' и посмотреть, получится ли вам другой результат (т. Е. Последнее чтение 'countRows (con2)' получает результат '1' – Alex
@Alex В этом случае 'con2' видит новую строку, вставленную' con1'. Но почему мой код не создает _phantom reads_ на уровне изоляции 'REPEATABLE_READ'? – MinecraftShamrock