事务(Transaction)
事务是由一系列对系统中数据进⾏访问与更新的操作所组成的⼀个程序执行逻辑单元。
一、事务的语法
1、 start transaction; 或者 begin;
开始事务
2.、rollback;
回滚 ----- 使得当前的修改被放弃
只能放弃commit之前的修改,commit之后rollback 无法放弃修改
3、 commit;
提交 ----- 使得当前的修改确认
二、事务的ACID特性
1、原子性(Atomicity)
事务的原⼦性是指事务必须是⼀个原子的操作序列单元。事务中包含的各项操作在⼀次执⾏过程中,只 允许出现两种状态之一。
(1)全部执行成功
(2)全部执行失败事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执⾏过程中出错, 会回滚到事务开始前的状态,所有的操作就像没有发⽣一样。也就是说事务是⼀个不可分割的整体,就 像化学中学过的原子,是物质构成的基本单位。
2、一致性 (Consistency)
事务的一致性是指事务的执⾏不能破坏数据库数据的完整性和一致性,一个事务在执⾏之前和执行之后,数据库都必须处以⼀致性状态。
比如:如果从A账户转账到B账户,不可能因为A账户扣了钱,⽽B账户没有加钱。
3、隔离性 (Isolation)
事务的隔离性是指在并发环境中,并发的事务是互相隔离的。也就是说,不同的事务并发操作相同的数据时,每个事务都有各自完整的数据空间。
⼀个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务是不能互相干扰的。
4、持久性 (Duration)
事务的持久性是指事务⼀旦提交后,数据库中的数据必须被永久的保存下来。即使服务器系统崩溃或服 务器宕机等故障。只要数据库重新启动,那么一定能够将其恢复到事务成功结束后的状态
三、事务的并发问题
1、脏读
读取到了没有提交的数据,
事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。(查询出的数据内容可能不一致))
读未提交(READ-UNCOMMITTED)隔离级别下测试
2、不可重复读
同⼀条命令返回不同的结果集(更新).
事务 A 多次读取同一数据,事务 B 在事务A 多次读取的过程中,对数据做了更新并提交,导致事务A多次读取同一数据时,结果不一致。(查询出的数据内容可能不一致)
读已提交(READ-COMMITTED)隔离级别下测试
3、幻读
重复查询的过程中,数据就发⽣了量的变化(insert, delete)(查询出的数据量可能会不一致)
可重复读(REPEATABLE-READ)隔离级别条件下测试
四、事务的隔离
1、四种事务隔离
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交(READ-UNCOMMITTED) | 允许 | 允许 | 允许 |
读已提交(READ_COMMITTED) | 禁止 | 允许 | 允许 |
可重复读(REPEATABLE-READ) | 禁止 | 禁止 | 可能出现 |
顺序读(SERIALIZABLE) | 禁止 | 禁止 | 禁止 |
4种事务隔离级别从上往下,级别越高,并发性越差,安全性就越来越高。
⼀般数据默认级别是 读以提交或可重复读
2、sql语句
-- 查看当前会话中事务的隔离级别
-- MySQL 8.0版本以前使用的命令
select @@tx_isolation;
-- MySQL 8.0版本后使用的命令
select @@transaction_isolation;
-- 设置当前会话中的事务隔离级别
set session transaction isolation level 隔离级别;
注意:
1、在设置隔离级别的时候 隔离级别两个单词中间是不加横线的,查询出来的结果是有的
2、设置隔离级别的只对当前会话有效
举个MySQL8以后的栗子
1、先查看当前会话事务隔离级别
2、然后修改当前会话隔离级别为 可重复读(REPEATABLE-READ)
-- 1、先查看当前会话事务隔离级别
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ |
+-------------------------+
1 row in set (0.00 sec)-- 2、然后修改当前会话隔离级别为 可重复读(REPEATABLE-READ)
mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)-- 检查当前会话隔离级别是否修改成功
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| READ-COMMITTED |
+-------------------------+
1 row in set (0.00 sec)
3、不同的隔离级别的锁的情况
- 读未提交(RU): 有行级的锁,没有间隙锁。它与RC的区别是能够查询到未提交的数据。
- 读已提交(RC):有行级的锁,没有间隙锁,读不到没有提交的数据。
- 可重复读(RR):有行级的锁,也有间隙锁,每次读取的数据都是一样的,并且没有幻读的情况。
- 序列化(S):有行级锁,也有间隙锁,读表的时候,就已经上锁了