目录
一、什么是事务
事务是一个不可分割的最小工作单元
事务只和数据库的增删改有关,一个完整的事务需要批量的增删改语句
二、事务的四大特点
1.原子性(A)
原子性是指事务是一个不可被分割的工作单元,其中的操作要么同时成功,要么同时失败
2.持久性(I)
持久性是指事务一旦提交以后,那么他对数据库的更改就是永久性的,接下来的其他操作或故障都不会改变提交的数据(永久性是指数据写回到磁盘中)
3.隔离性(D)
事务和事务之间是相互隔离的(自己做自己的事情,但是它是很难实现的)
4.一致性(C)
指事务的执行结果必须是数据库从一个状态转换为另一个状态
比如:张三和李四各有500(原来状态);张三给李四转了100,现在张三400,李四600(现在状态)
三、怎么使用事务
分三个阶段:1.开启事务 2.增删改执行语句 3.提交事务
例:
一张表:
1.事务提交-----张三(id=1)给李四(id=2)转100
先把钱改回去,都是500
start transaction;//开启事务
update act set balance=400 where id=1;
update act set balance=600 where id=2;
commit;//提交事务
2.事务提交 (中间出错了)-----张三(id=1)给李四(id=2)转100
先把钱改回去,都是500
start transaction;
update act set balance=400 where id=1;
sssss
update act set balance=600 where id=2;
rollback; #如果出现了错误,那么马上回滚为原来的状态
commit; #如果没有错误,则事务提交
中间出错了,所以事务回滚,还是500和500
四、事务的并发问题
1.脏读问题(读未提交)
一个事务读取到了另一个事务修改但未提交的数据
出现脏读说明事物的隔离级别很弱
例:
两个事务A,B
可以看出:事务B读取到了事务A修改但是没有提交的数据(万一事务A回滚了怎么办)
这就是脏数据
2.不可重复读(读已提交)
在同一个事务内多次读取同一个数据,数据前后不一致
例:
对A来说前后不一致
3.幻读
五、隔离级别
1.读未提交
设置读未提交的隔离级别:
set global transaction isolation level read uncommitted;
两个事务:
开启事务A和B:
事务B读取用户信息:
事务A将用户名改为了aaa:
事务B读取用户信息:
可以看到事务B读取了事务A修改但未提交的数据,是最低的隔离级别
2.读已提交
设置读已提交的隔离级别
set global transaction isolation level read committed;
两个事务:
开启两个事务:
事务A查询用户信息:
事务B修改用户信息,然后提交事务
然后事务A再查询:
可以看出,单从事务A来说,两次查询的数据是不一样的,事务A读取到了事务B已经提交的数据,解决了脏读问题
3.可重复读
设置可重复读的隔离级别(mysql默认的隔离级别),脏读问题在可重复读的事务隔离级别中不存在的
set global transaction isolation level repeatable read;
两个事务AB:
开启事务AB:
事务A查询用户信息:
事务B添加一条数据,然后事务A和事务B再查询:
然后事务B提交,事务A和事务B再查询:
事务B再添加一条数据,事务A和事务B再查询:
可以看出,事务B添加是成功的,但是事务A还是原来的数据,这就是可重复读,读取的是备份数据而不是真正的数据
4.串行化
串行化指的是事务A在执行期间,其他事务一律等待
设置串行化的隔离级别
set global transaction isolation level serializable;
两个事务AB:
开启事务AB:
现在事务A先做一个修改,然后事务B做,会发现运行一直不出结果,然后事务A提交之后,事务B才会运行:
串行化
5.隔离级别与一致性的关系
读未提交哪个问题都没解决;读已提交解决了脏读;可重复读都解决了(但是幻读只有采用InnoDB引擎才是解决了)
|---------------------------------|----|-------|-----------|
| 并发问题 --------------------- 隔离级别 | 脏读 | 不可重复读 | 幻读 |
| 读未提交 | × | × | × |
| 读已提交 | √ | × | × |
| 可重复读 | √ | √ | √(InnoDB) |
| 串行化 | √ | √ | √ |