MySQL版本:8.0.15
目录
一、基本概念
数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。
二、事务操作
1、基本操作
开启事务:start transaction
回滚:rollback
提交:commit
2、MySQL数据库中,事务自动提交
- 一条DML(增删改)语句会自动提交一次事务。
- 事务提交的两种方式:
1. 自动提交:MySQL就是自动提交的。一条DML(增删改)语句会自动提交一次事务。
2. 手动提交:Oracle 数据库是手动提交事务。需要先开启事务,再提交。
3、MySQL数据库修改事务提交方式:
① 查看MySQL数据库的事务提交方式
1 代表自动提交;
0 代表手动提交。
SELECT @@autocommit;
0 代表事务提交方式为手动提交,使用SQL语句修改数据库的值后,使用查询语句看到的已修改的数据都是临时数据。此时,关闭数据库重新打开,数据会自动还原成被修改之前的数据!此时需要手动提交事务。
② 修改默认提交方式:
SET @@autocommit = 0; //事务手动提交
SET @@autocommit = 1; //事务自动提交
三、事务的四大特征:ACID
3.1 原子性(atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
3.2 持久性(durability)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
比如银行转账,如果用户A和用户B两者的钱加起来一共是3000,那么不论A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是3000,这就是事务的一致性。
3.3 隔离性(isolation)
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
3.4 一致性(consistency)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
四、事务的隔离级别
4.1 概念
多个事务之间隔离的,相互独立。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别,就可以解决这些问题。
4.2 问题
当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种问题:
1️⃣脏读
在一个事务处理过程中,读取了另一个未提交的事务中的数据。
2️⃣不可重复读(虚读)
在同一个事务中,两次读取到的数据不一样。
3️⃣幻读
幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。
4.3 隔离级别
序号 | 隔离级别 | 概念 | 产生的问题 |
---|---|---|---|
1 | read uncommitted | 读未提交 | 脏读,不可重复读,幻读 |
2 | read committed | 读已提交【只有提交了数据,另一个事务才能读到(Oracle默认)】 | 不可重复读,幻读 |
3 | repeatable read | 可重复读(MySQL默认) | 幻读 |
4 | serializable | 串行化 | 可以解决所有问题 |
注意:隔离级别从1到4,安全性越来越高,但是效率越来越低。
4.4 MySQL查询隔离级别
1️⃣ MySQL8.0及其以上的版本:
SELECT @@transaction_isolation;
2️⃣ MySQL8.0及其以前的版本:
SELECT @@tx_isolation;
4.5 MySQL设置隔离级别和注意事项
首先,设置数据库的隔离级别必须在开启事务之前!
1️⃣ 设置全局隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
注意:对当前session无效,数据库重启之后,该操作才会生效。
2️⃣设置当前连接的隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
注意:仅对当前连接有效,数据库重启后该设置消失,还原回设置之前的级别。
此处所指的‘连接’,对应于JDBC中的Connection对象。