为什么'可重复阅读' java中的隔离级别让我免于幻影读取'?

时间:2017-02-10 00:42:37

标签: java mysql jdbc isolation-level

我用“幻读”编写代码'如果隔离级别不可序列化,我的代码应该打印不同的值,但我有可重复的读取'隔离级别,它像序列化一样工作。它显示我相同的数字,但应该第二次显示更大的数字。为什么这样?我是MySql数据库。这是我的例子:

public class PhantomReadLesson {
static String url = "jdbc:mysql://localhost:3306/Lessons";
static String username = "root";
static String password = "1";
public static void main(String[] args) throws SQLException, InterruptedException {
    try(Connection conn = DriverManager.getConnection(url, username, password);
        Statement statement = conn.createStatement()) {
        conn.setAutoCommit(false);
        conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
        ResultSet rs = statement.executeQuery("Select count(*) from Books");
        while(rs.next()){
            System.out.println(rs.getInt(1));
        }
        new OtherTransaction2().start();
        Thread.currentThread().sleep(1000);
        rs = statement.executeQuery("Select count(*) from Books");
        while(rs.next()){
            System.out.println(rs.getString(1));
        }
    }
}

static class OtherTransaction2 extends Thread {
    @Override
    public void run() {
        try(Connection conn = DriverManager.getConnection(url, username, password);
            Statement stmt = conn.createStatement()) {
            conn.setAutoCommit(false);
            conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
            stmt.executeUpdate("insert into Books (name) VALUES ('new Row')");
            conn.commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
}

我模仿幻像读物'在这里。如果我使用' repeatable_read'或者'可序列化的'它显示相同的数字,如果使用' read_commmited'或者' read_uncomited'它会显示不同的数字。但根据java doc https://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html,只有可以序列化的“幻像读取”保存。那么为什么可重复读取级别保存来自' phanotom read'?

1 个答案:

答案 0 :(得分:1)

来自MySQL docs(约<Google> To get test ads on this device, call: request.testDevices = @[ kGADSimulatorID ]; ):

  

同一事务中的一致读取读取快照   由第一次阅读建立。

Consistent reads

  

使用快照信息呈现查询的读取操作   结果基于某个时间点,而不管执行的更改   其他交易同时运行。

当您将自动提交设置为REPEATABLE READ时,这意味着两个选择都在同一个事务中执行。那么,你的担忧是什么?看起来它的工作方式与预期的一样。

另请注意this remark:

  

假设您在默认的REPEATABLE READ隔离中运行   水平。发出一致读取时(即普通SELECT)   声明),InnoDB为您的交易提供了一个时间点   您的查询查看数据库。如果另一个事务删除a   分配您的时间点后的行和提交,您没有看到   已被删除的行。插入和更新的处理方式相似。