什么是事务

在实际的业务开发中,有些业务操作要多次访问数据库。

一个业务要发送多条SQL语句给数据库执行。

需要将多次访问数据库的操作视为一个整体来执行,要么所有的SQL语句全部执行成功。

如果其中有一条SQL语句失败,就进行事务的回滚,所有的SQL语句全部执行失败。

简而言之,事务指的是逻辑上的一组操作,组成这组操作的各个单元要么全都成功,要么全都失败。

事务的作用

保证在一个事务中多次操作数据库表中数据时,要么全都成功,要么全都失败。

image-moly.png

手动提交事务

-- 开启手动控制事务
start transaction;
-- 提交事务
commit;
-- 回滚事务
rollback;

自动提交事务

-- 查看当前autocommit模式
show variables like '%commit%';
-- 设置自动提交的参数
set autocommit = 0; -- 0:OFF 1:ON

原理

image-zesz.png

  1. 一个用户登录成功以后,服务器会创建一个临时日志文件。日志文件用来保存用户事务状态。
  2. 如果没有使用事务,则所有的操作直接写到数据库中,不会使用日志文件。
  3. 如果开启事务,将所有的写操作写到日志文件中。
  4. 如果这时用户提交了事务,则将日志文件中所有的操作写到数据库中。
  5. 如果用户回滚事务,则日志文件会被清空,不会影响到数据库的操作。

事务四大特性(ACID)

原子性(Atomicity)

事务包装的一组sql(一组业务逻辑)是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

一致性(Consistency)

事务前后数据的完整性必须保持一致。

隔离性(Isolation)

多个用户并发的访问数据库时,一个用户的事务不能被其他用户的事务干扰,多个并发的事务之间要相互隔离。

持久性(Durability)

一个事务一旦被提交,它对数据库的改变将是永久性的,哪怕数据库发生异常,重启之后数据亦然存在。

事务的并发访问引起的问题

脏读

一个事务读取到了另一个事务中尚未提交的数据。

image-aovq.png

注意:

脏读的前提是没有事务的隔离性。

不可重复读

一个事务中两次读取的数据内容不一致。

update引起

幻读

一个事务内读取到了别的事务插入或者删除的数据,导致前后读取记录行数不同。

insertdelete 引起

事务的隔离级别

级别 名字 隔离级别 脏读 不可重复读 幻读 数据库默认隔离级别
1 读未提交 read uncommitted
2 读已提交 read committed Oracle和SQL Server
3 可重复读 repeatable read MySQL
4 串行化 serializable

设置隔离级别

-- 查询全局事务隔离级别
show variables like '%isolation%';
-- 或
select @@tx_isolation;
-- 设置隔离级别
set global transaction isolation level 隔离级别;

注意:

mysql5.6后,设置隔离级别为uncommitted,那么修改数据会报错。