JDBC - 事务的ACID特性



什么是事务?

事务是访问并更新数据库内容的单个逻辑操作单元。

事务的ACID特性

为了保持数据库一致性,事务还必须保持某些特性,这些特性称为ACID特性A代表原子性,C代表一致性,I代表隔离性,D代表持久性。

  • 原子性 − 事务涉及按顺序执行的一组操作。原子性表示这组操作要么全部成功,要么全部失败。

  • 一致性 − 此特性确保只有一致的数据添加到数据库。如果发生任何错误,数据库将恢复到初始状态。

  • 隔离性 − 事务必须彼此隔离,否则数据可能会损坏。隔离级别可以是读未提交、读已提交、可重复读和可串行化。这些将在下一节中描述。

  • 持久性 − 此特性确保已完成的事务将适当地持久化数据,即使在服务器故障/系统崩溃的情况下也是如此。

脏读、不可重复读、幻读

在理解隔离性之前,让我们先了解以下基本概念:

  • 脏读 − 用户A向表中插入一行。用户B选择该行。用户A取消事务。现在,B已经对该行进行了更改,但是该行不再存在于数据库中了。

  • 不可重复读 − 用户A读取一行。用户B更新该行。用户A再次读取该行,并看到更新后的结果。

  • 幻读 − 用户A读取表中满足SQL中WHERE条件的所有行。用户B向满足WHERE条件的同一查询中添加一行。用户A再次执行SELECT操作,并找到添加的行。

隔离级别

以下是java.sql包中存在的五个主要隔离级别。

序号 隔离级别 描述
1 TRANSACTION_NONE 不支持事务。
2 TRANSACTION_READ_UNCOMMITTED 未保存的数据对事务可见。所有数据不一致性都是可能的。
3 TRANSACTION_READ_COMMITTED 防止脏读。对事务的所有更改只有在事务提交后才可见。
4 TRANSACTION_REPEATABLE_READ 防止脏读、不可重复读。第二个事务不能读取、更新或删除第一个事务选择的行。不防止幻读。
5 TRANSACTION_SERIALIZABLE 最严格的隔离级别。防止脏读、不可重复读、幻读。

上述隔离级别可以通过java.sql包中的Connection对象的setIsolationLevel方法设置。例如,

Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1/TUTORIALSPOINT", "user", "password");
conn.setIsolationLevel(Connection.TRANSACTION_READ_COMMITTED);

在MySQL中设置隔离级别

隔离级别也可以在数据库中设置。对于MySQL:

mysql> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

其他允许的值如下:

  • READ COMMITTED

  • READ UNCOMMITTED

默认隔离级别为REPEATABLE READ

广告