数据库事务:验证隔离级别-不可重复读

说明

本文中的代码,是对 数据库事务:脏读、不可重复读、幻读 中 不可重复读 的验证,所以需要先看该文中的 不可重复读

注意:为了更好的理解代码,代码尽量简洁,所以 不严谨

查询类

有两个 main() 方法:

  • 第一个 main 方法:启用事务,事务隔离级别设置 读提交,执行 多次查询,第2次查询,可以查询到 另一个类 修改的数据,即:一个事务中,多次查询结果不一致,违反事务一致性

  • 第二个 main 方法:启用事务,事务隔离级别设置 可重复读,执行 多次查询,第2次查询,不会查询到 另一个类 修改的数据,即:一个事务中,多次查询结果一致

package test;


import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public class S2不可重复读1_查询 {

    /**
     * 查询时,启用事务,事务隔离级别设置 读提交
     * @param args
     */
    public static void main1(String[] args) throws SQLException {
        String driver = "com.mysql.cj.jdbc.Driver";
        String url="jdbc:mysql://localhost:3306/test?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
        Connection connection = null;
        try {
            connection = Db.connect(driver,url,"root","root");
            // XXXXX 设置事务隔离级别为:读提交 XXXXXXXX
            connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
            connection.setAutoCommit(false);

            List<Map> list = Db.query(connection,"select id,username,password from user ");
            System.out.println(list);

            System.out.println("延迟10秒");
            Thread.sleep(10000);

            List<Map> list2 = Db.query(connection,"select id,username,password from user ");
            System.out.println(list2);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(connection!=null){
                connection.close();
            }
        }
    }

    /**
     * 查询时,启用事务,事务隔离级别设置 可重复读
     * @param args
     */
    public static void main(String[] args) throws SQLException {
        String driver = "com.mysql.cj.jdbc.Driver";
        String url="jdbc:mysql://localhost:3306/test?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
        Connection connection = null;
        try {
            connection = Db.connect(driver,url,"root","root");
            // XXXXX 设置事务隔离级别为:读提交 XXXXXXXX
            connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
            connection.setAutoCommit(false);

            List<Map> list = Db.query(connection,"select id,username,password from user ");
            System.out.println(list);

            System.out.println("延迟10秒");
            Thread.sleep(10000);

            List<Map> list2 = Db.query(connection,"select id,username,password from user ");
            System.out.println(list2);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(connection!=null){
                connection.close();
            }
        }
    }
}

修改类

package test;

import java.sql.Connection;
import java.sql.SQLException;

public class S2不可重复读2_修改数据 {

    public static void main(String[] args) {
        String driver = "com.mysql.cj.jdbc.Driver";
        String url="jdbc:mysql://localhost:3306/test?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
        Connection connection = null;
        String sql = "update user set password = '111111' where id = 2";

        try {
            connection = Db.connect(driver,url,"root","root");

            // 不自动提交
            connection.setAutoCommit(false);
            int n = Db.update(connection,sql);

            System.out.println("提交事务");
            connection.commit();
        } catch (Exception e) {
            e.printStackTrace();
            try {
                System.out.println("回滚事务");
                connection.rollback();
            } catch (SQLException ex) {
                e.printStackTrace();
            }
        }finally {
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

原文出处:/show_1IX78F6I85qR.html