一.介绍
事务用于保证数据的一致性,它由一组dml(增删改)语句组成,该组的dml语句要么全部成功,要么全部失败。最经典的例子就是转账,在转账时我们要保证数据的一致性,不能一个人转了钱,但另一个人没有收到。当执行dml语句时,MySQL会在表上加锁,用来保证数据的一致性。
事务的ACID特性:
1)原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
2)一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另一个一致性状态。
3)隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
4)持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
二.基本操作
操作 | 说明 |
start transaction | 开启一个事务 |
savepoint 点名 | 设置保存点 |
rollback | 回退全部事务 |
rollback to 点名 | 回退到点名处 |
commit | 提交事务 |
保存点:就像是游戏里的存档,我们不小心错过了某个装备,我们可以通过读档回到原来的保存点。回退就像是读档,回退后,在保存点后面写的dml语句全部作废。
提交事务后,无法回退,没有“后悔药”了。
注意事项:
1)如果不开始事务,在默认情况下,dml操作是自动提交的,不能回滚;
2)如果开始一个事务,没有创建保存点。可以执行rollback,默认就是回退到你事务开始的状态;
3)可以在这个事务中,创建多个保存点;可以在事务没有提交前,选择回退到哪个保存点;
4)MySQL事务机制需要innodb的存储引擎才可以使用,myisam不行。
三.隔离级别
1.介绍
多个连接开启各自事务操作数据库时,数据库系统要负责隔离操作,以保证各个连接在获取数据时的准确性。如果不考虑隔离性,可能会发生如下问题:脏读、不可重复读、幻读。
MySQL隔离级别定义了事务与事务之间的隔离程度。
隔离级别 | 脏读 | 不可重复读 | 幻读 | 加锁读 |
read uncommitted(读未提交) | V | V | V | 不加锁 |
read committed(读已提交) | X | V | V | 不加锁 |
repeatable read(可重复读) | X | X | V | 不加锁 |
serializable(可串行化) | X | X | X | 加锁 |
虽然隔离级别从上到下的安全性越来越高,但是从上到下的并发性能是越来越差的。
2.相关语句
//查看当前会话隔离级别
select @@transaction_isolation;
//查看系统当前隔离级别
select @@global.transaction_isolation;
//设置当前会话隔离级别
set session transaction isolation level 隔离级别;
//设置系统当前隔离级别
set global transaction isolation level 隔离级别;
3.脏读、不可重复读、幻读
这三个在面试的时候很喜欢问,这里就给大家解释的明明白白。
脏读:A、B连上了数据库(操作同一张表)开始了事务,A插入了两条数据,并执行了,但没有提交事务。这时,B查询了这张表,结果查到了A刚刚插入的两条数据。这就是脏读,明明没有提交,怎么可能能查到呢。
不可重复读:A、B连上了数据库(操作同一张表)开始了事务,A插入了两条数据,并执行了,提交事务。这时,B查询了这张表,结果查到了A刚刚插入的两条数据。这就是不可重复读。有人可能会问:这又什么问题,不都提交了吗?不对,B拿到的那张表是刚开始事务的那张表,按理来说B是看不到A改完后的表,B看到的一直是最开始的那张表才对。
幻读:A、B连上了数据库(操作同一张表)开始了事务,A修改了某一数据,并执行了,提交事务。这时,B查询了这张表,结果查到了A修改后的表。这就是幻读。解释还是和上面的一样。
4.全局修改
在配置文件中修改:
找到这个文件,在文件中加上:
transaction-isolation = 隔离级别;
隔离级别就加上自己想设置的级别即可。