风海网 > 生活 > 正文

​transaction(MySQL - 事务(Transaction)详解)

2024-01-24 04:11 来源:风海网 点击:

transaction(MySQL - 事务(Transaction)详解)

一、事务(Transaction)定义

事务:一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务。

●一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成。

●在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表支持事务。

●事务处理可以用来维护数据库的完整性,保证成批的SQL语句要么全部执行,要么全部不执行。

●事务只和DML语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同

●MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

二、事务的四大特征(ACID)

一般来说,事务是必须满足4个条件(ACID):Atomicity(原子性或不可分割性)、Consistency(一致性)、Isolation(隔离性或独立性)、Durability(持久性)

原子性(Atomicity):

一组事务,要么成功;要么撤回,即事务在执行过程中出错会回滚到事务开始前的状态。

●一致性(Consistency) :一个

事务不论是开始前还是结束后,数据库的完整性都没有被破坏。因此写入的数据必须完全符合所有预设规则(资料精确度、串联性以及后续数据库能够自发完成预定工作)。

●隔离性(Isolation):

数据库允许多个事务并发的同时对其数据进行读写修改等操作,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离可分为:Read uncommitted(读未提交)、Read committed(读提交)、Repeatable read(可重复读)、Serializable(串行化)。

●持久性(Durability):

事务在处理结束后对数据做出的修改是永久的,无法丢失

2.1 隔离性(Isolation)的级别

事务A和事务B之间具备隔离性

●隔离性有以下4个隔离级别:

1、都未提交:read uncommitted

●事务A和事务B

●在该隔离级别,所有事物都可以看到其他未提交事务的执行结果

●本隔离级别很少用于实际应用

●因为他的性能也不比其他级别好多少,读取未提交的数据,也被称之为脏读(Dirty Read)

2、读已提交:read committed

●大多数数据库系统的默认隔离级别(但不是MySQL默认的)

●满足了隔离的简单定义:一个事物在提交之前对其他事物是不可见的,这种隔离级别也支持所谓的不可重复读取(Nonerepeatable Read),因为同一事务的其他实例在该实例处理其他期间可能会有新的commit,所以同一select可能返回不同结果。

3、可重复读:repeatable read

●MySQL默认的隔离级别

●确保同一事务的多个实例在并发读取数据时,会看到同样的数据行

●不过这会导致另一个棘手的问题,幻读(Phantom Read)

●幻读指当用户读取某一范围的数据行时,另一个事物又在该范围内插入了新行,当用户再读取该范围内的数据时,会发现有新的"幻影"行,Innodb和Falcon存储引擎通过多版本并发控制(MVCC)机制解决了该问题

4、串行化:serializable

●最高的隔离级别

●通过强制事物排序,使事务之间不可能相互冲突,从而解决了幻读问题

●简言之,它是在每个读的数据行上加共享锁

●在这个级别,可能导致大量的超时现象和锁竞争

2.2 隔离性的作用

如果没有隔离,会发生的几种问题

脏读(Dirty Read)

一个事务处理过程里读取了另一个未提交的事务中的数据

●不可重复读(NonRepeatable Read)

对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询的间隔期间,另外一个事务修改并提交了该数据。

不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如对于同一个数据A和B依次查询就可能不同,A和B就可能打起来了……。

●幻读(Phantom Read)

在一个事务中读取到了别的事务插入的数据,导致前后不一致。

事务A 按照一定条件进行数据读取,期间事务B插入了相同搜索条件的新数据,事务A再次按照原先条件进行读取时,发现了事务B 新插入的数据

三、关于事务的术语

●事务相关的一些术语:

●开启事务:Start Transaction

●事务结束:End Transaction

●提交事务:Commit Transaction

●回滚事务:Rollback Transaction

四、事务如何开始,有何标识?事务如何结束,有何标识?

●开启标志:

●执行一条DML语句,即开始进行事务。

●eg:insert into、update、delete

●结束标志:

●提交:成功的结束,将所有的DML语句操作历史记录和底层硬盘数据来一次同步

●回滚:失败的结束,将所有的DML语句操作历史记录全部清空

4.1 示例:事务的提交

●提交(事务成功)

mysql> select * from users;

+------+------+

| id | name |

+------+------+

| 1 | abc |

+------+------+

1 row in set (0.00 sec)

mysql> start transaction; #开始事务

Query OK, 0 rows affected (0.00 sec)

mysql> insert into users values(2,'test'); #执行DML语句

Query OK, 1 row affected (0.00 sec)

mysql> commit; #提交

Query OK, 0 rows affected (0.00 sec)

mysql> select * from users; #DML语句插入的数据已存在于表中

+------+------+

| id | name |

+------+------+

| 1 | abc |

| 2 | test |

+------+------+

2 rows in set (0.00 sec)

4.2 示例:事务的回滚

●回滚(事务失败)

mysql> select * from users;

+------+------+

| id | name |

+------+------+

| 1 | abc |

| 2 | test |

+------+------+

2 rows in set (0.00 sec)

mysql> start transaction; #开始事务

Query OK, 0 rows affected (0.00 sec)

mysql> insert into users values(3,'xx'); #执行DML语句

Query OK, 1 row affected (0.00 sec)

mysql> rollback; #回滚

Query OK, 0 rows affected (0.00 sec)

mysql> select * from users; #DML语句插入的数据未写入表中

+------+------+

| id | name |

+------+------+

| 1 | abc |

| 2 | test |

+------+------+

2 rows in set (0.00 sec)

五、事务的控制语句

1、开始一个事务

●begin

●start transaction

2、设置保存点,一个事务中可以有多个保存点

●savepoint 保存点名称

3、提交事务,并使数据库中进行的所有修改成为永久性的

●commit work

●commit

4、回滚结束用户的事务,并撤销正在进行的所有未提交的修改

●rollback work

●rollback

5、删除一个事务的保存点,若没有指定保存点,执行该语句操作会报错

●release savepoint 保存点名称

6、将事务滚回标记点

●rollback to 标记点

7、设置事务的隔离级别

set transaction isolation level[READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]

InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE