美文网首页数据库
事务基本概念【转载】

事务基本概念【转载】

作者: elijah777 | 来源:发表于2019-06-19 23:43 被阅读0次

事务基本概念

1. 事务(Transaction)的四个属性(ACID)

  1. 原子性(Atomic)** 对数据的修改要么全部执行,要么全部不执行。
  2. 一致性(Consistent) 在事务执行前后,数据状态保持一致性。
  3. 隔离性(Isolated) 一个事务的处理不能影响另一个事务的处理。
  4. 持续性(Durable) 事务处理结束,其效果在数据库中持久化。

2. 事务并发处理可能引起的问题

  1. 脏读(dirty read)**:一个事务读取了另一个事务尚未提交的数据,
  2. 不可重复读(non-repeatable read) :一个事务的操作导致另一个事务前后两次读取到不同的数据
  3. 幻读(phantom read) :一个事务的操作导致另一个事务前后两次查询的结果数据量不同。

3. JDBC的事务支持

JDBC对事务的支持体现在三个方面:

1.自动提交模式(Auto-commit mode)

Connection提供了一个auto-commit的属性来指定事务何时结束。 a.当auto-commit为true时,当每个独立SQL操作的执行完毕,事务立即自动提交,也就是说每个SQL操作都是一个事务。一个独立SQL操作什么时候算执行完毕。

1.JDBC规范是这样规定的:对数据操作语言(DML,如insert,update,delete)和数据定义语言(如create,drop),语句一执行完就视为执行完毕。 2.对select语句,当与它关联的ResultSet对象关闭时,视为执行完毕。 3.对存储过程或其他返回多个结果的语句,当与它关联的所有ResultSet对象全部关闭,所有update count(update,delete等语句操作影响的行数)和output parameter(存储过程的输出参数)都已经获取之后,视为执行完毕。

b. 当auto-commit为false时,每个事务都必须显示调用commit方法进行提交,或者显示调用rollback方法进行回滚。auto-commit默认为true。

2.事务隔离级别(Transaction Isolation Levels)

JDBC提供了5种不同的事务隔离级别,在Connection中进行了定义。 JDBC定义了五种事务隔离级别:

TRANSACTION_NONE JDBC驱动不支持事务 TRANSACTION_READ_UNCOMMITTED 允许脏读、不可重复读和幻读。 TRANSACTION_READ_COMMITTED 禁止脏读,但允许不可重复读和幻读。 TRANSACTION_REPEATABLE_READ 禁止脏读和不可重复读,单运行幻读。 TRANSACTION_SERIALIZABLE 禁止脏读、不可重复读和幻读。

3.保存点(SavePoint)

JDBC定义了SavePoint接口,提供在一个更细粒度的事务控制机制。当设置了一个保存点后,可以rollback到该保存点处的状态,而不是rollback整个事务。

Connection接口的setSavepoint和releaseSavepoint方法可以设置和释放保存点。 JDBC规范虽然定义了事务的以上支持行为,但是各个JDBC驱动,数据库厂商对事务的支持程度可能各不相同。如果在程序中任意设置,可能得不到想要的效果。为此,JDBC提供了DatabaseMetaData接口,提供了一系列JDBC特性支持情况的获取方法。比如,通过DatabaseMetaData.supportsTransactionIsolationLevel方法可以判断对事务隔离级别的支持情况,通过DatabaseMetaData.supportsSavepoints方法可以判断对保存点的支持情况。

4. 事务隔离级别

Read uncommit(读未提交) Read commit(读已提交) Repeatable read(可重复读) Serializable(序列化)

a、读未提交 Read Uncommitted

在该隔离级别,所有事务都可以看到其它事务未提交的内容数据。此隔离级别没有解决任何并发问题,不常用。

Read Uncommitted是隔离级别最低的一种事务级别。在这种隔离级别下,一个事务会读到另一个事务更新后但未提交的数据,如果另一个事务回滚,那么当前事务读到的数据就是脏数据,这就是脏读(Dirty Read)。

首先,我们准备好students表的数据,该表仅一行记录:

mysql> select * from students;
+----+-------+
| id | name  |
+----+-------+
|  1 | Alice |
+----+-------+
1 row in set (0.00 sec)

然后,分别开启两个MySQL客户端连接,按顺序依次执行事务A和事务B:

时刻 事务A 事务B
1 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
2 BEGIN; BEGIN;
3 UPDATE students SET name = 'Bob' WHERE id = 1;
4 SELECT * FROM students WHERE id = 1;
5 ROLLBACK;
6 SELECT * FROM students WHERE id = 1;
7 COMMIT;

事务B 第一次读4的和第二次5读的数据不一致 脏数据

当事务A执行完第3步时,它更新了id=1的记录,但并未提交,而事务B在第4步读取到的数据就是未提交的数据。

随后,事务A在第5步进行了回滚,事务B再次读取id=1的记录,发现和上一次读取到的数据不一致,这就是脏读。

可见,在Read Uncommitted隔离级别下,一个事务可能读取到另一个事务更新但未提交的数据,这个数据有可能是脏数据。

b、读已提交 Read Committed

在该隔离级别,一个事务只能读取其它事务已经提交的内容数据。此隔离级别解决了脏读,但没有解决不可重复读和幻读,是ORACLE的默认隔离级别。

不可重复读是指,在一个事务内,多次读同一数据,在这个事务还没有结束时,如果另一个事务恰好修改了这个数据,那么,在第一个事务中,两次读取的数据就可能不一致。

我们仍然先准备好students表的数据:

mysql> select * from students;
+----+-------+
| id | name  |
+----+-------+
|  1 | Alice |
+----+-------+
1 row in set (0.00 sec)

然后,分别开启两个MySQL客户端连接,按顺序依次执行事务A和事务B:

时刻 事务A 事务B
1 SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
2 BEGIN; BEGIN;
3 SELECT * FROM students WHERE id = 1;
4 UPDATE students SET name = 'Bob' WHERE id = 1;
5 COMMIT;
6 SELECT * FROM students WHERE id = 1;
7 COMMIT;

事务B 读到两次3和6不同的数据

当事务B第一次执行第3步的查询时,得到的结果是Alice,随后,由于事务A在第4步更新了这条记录并提交,所以,事务B在第6步再次执行同样的查询时,得到的结果就变成了Bob,因此,在Read Committed隔离级别下,事务不可重复读同一条记录,因为很可能读到的结果不一致。

c、可重复读 Repeatable Read

在该隔离级别,能保证一个事务之间的多个实例在并发下能读取同一数据。此隔离级别解决了脏读和不可重复读,是MYSQL的默认级别。

在Repeatable Read隔离级别下,一个事务可能会遇到幻读(Phantom Read)的问题。

幻读是指,在一个事务中,第一次查询某条记录,发现没有,但是,当试图更新这条不存在的记录时,竟然能成功,并且,再次读取同一条记录,它就神奇地出现了。

我们仍然先准备好students表的数据:

mysql> select * from students;
+----+-------+
| id | name  |
+----+-------+
|  1 | Alice |
+----+-------+
1 row in set (0.00 sec)

然后,分别开启两个MySQL客户端连接,按顺序依次执行事务A和事务B:

时刻 事务A 事务B
1 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
2 BEGIN; BEGIN;
3 SELECT * FROM students WHERE id = 99;
4 INSERT INTO students (id, name) VALUES (99, 'Bob');
5 COMMIT;
6 SELECT * FROM students WHERE id = 99;
7 UPDATE students SET name = 'Alice' WHERE id = 99;
8 SELECT * FROM students WHERE id = 99;
9 COMMIT;

事务B在第3步第一次读取id=99的记录时,读到的记录为空,说明不存在id=99的记录。随后,事务A在第4步插入了一条id=99的记录并提交。事务B在第6步再次读取id=99的记录时,读到的记录仍然为空,但是,事务B在第7步试图更新这条不存在的记录时,竟然成功了,并且,事务B在第8步再次读取id=99的记录时,记录出现了。

d、序列化 Serializable

这是最高的隔离级别,在此隔离级别,事务事务之间只能顺序执行,使之没有任何冲突。序列化解决了脏读,不可重复读和幻读。 隔离级别越高,越能保证数据的完整性和一致性,但是对并发的效率就越低。因此并不是隔离级别越高越好,应根据具体的业务场景选用合适的事务隔离级别,如果没有特别重要的情景,一般都不会使用Serializable隔离级别。

默认隔离级别

如果没有指定隔离级别,数据库就会使用默认的隔离级别。在MySQL中,如果使用InnoDB,默认的隔离级别是Repeatable Read。

2019/6/19晚 于成都
文章内容参考与互联网博客以及廖师兄的文章

参考内容:

https://www.liaoxuefeng.com/wiki/1177760294764384/1179611198786848

https://www.cnblogs.com/fjdingsd/p/5273008.html

相关文章

  • 事务基本概念【转载】

    事务基本概念 1. 事务(Transaction)的四个属性(ACID) 原子性(Atomic)** 对数据的修改...

  • 数据库事务管理

    事务基本概念 《Transaction 那点事儿》这篇文章通俗易懂的讲解了事务的基本概念、事务特性、引发的问题、J...

  • 事务

    事务基本概念 事务特性 ACID(Atomicity、Consistency、Isolation、Durabili...

  • Spring Transaction的4种实现方式

    一、基本概念 1、事务传播行为 PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果...

  • 事务-基本概念

    1、什么是事务? 事务是指单一逻辑工作单元的集合( 比如 支付宝a转账给b的时候 要保证 a的金额减少和b的金额增...

  • Spring事务管理

    事务 事务的基本概念事务指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败。 事务的特性原子性:事务是一个...

  • Spring事务(一)Spring事务的使用介绍

    基本概念 Spring家事务中的几个关键类: TransactionManagerPlatformTransact...

  • 关联规则-算法原理与案例

    一. 基本概念 1.1 概述 ✓ 关联规则(Association Rules)反映一个事务与其他事务之间的相互依...

  • spring | 事务传播机制

    基本概念 spring事务传播机制是指,包含多个事务的方法在相互调用时,事务是如何在这些方法见传播的。既然是“事务...

  • 6)InnoDB事务

    事务的基本概念 事务的四个特性: |-- 原子性atomicity,一个事务是不可分割的工作单位,事务中的操作要么...

网友评论

    本文标题:事务基本概念【转载】

    本文链接:https://www.haomeiwen.com/subject/jrkrqctx.html