数据库事务:验证隔离级别-幻读 作者:马育民 • 2024-02-11 17:47 • 阅读:10021 # 说明 本文中的代码,是对 [数据库事务:脏读、不可重复读、幻读](https://www.malaoshi.top/show_1IX9gVCVzZP.html "数据库事务:脏读、不可重复读、幻读") 中 **幻读** 的验证,所以需要先看该文中的 幻读 **注意:**为了更好的理解代码,**代码尽量简洁**,所以 **不严谨** ### 查询类 有两个 `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 S3幻读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_REPEATABLE_READ); connection.setAutoCommit(false); List list = Db.query(connection,"select id,username,password from user "); System.out.println(list); System.out.println("延迟10秒"); Thread.sleep(10000); List list2 = Db.query(connection,"select id,username,password from user for update"); 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_SERIALIZABLE); connection.setAutoCommit(false); List list = Db.query(connection,"select id,username,password from user "); System.out.println(list); System.out.println("延迟10秒"); Thread.sleep(10000); List list2 = Db.query(connection,"select id,username,password from user for update "); 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 S3幻读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 = "delete from user 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(); } } } } } ``` 参考: https://blog.csdn.net/nandao158/article/details/116007366 原文出处:https://malaoshi.top/show_1IX78FhLjeSk.html