数据库事务的四大特性以及事务的隔离级别详解
(一) 事务定义
事务就是一个对数据库操作的序列,是一个不可分割的工作单位,要不这个序列里面的操作全部执行,要不全部不执行。
事务的优点
用术语来描述就是事务的好处在于:
当你需要对多个表进行相关性操作时,使用BeginTrans()开启事务,然后操作,
如果中间哪个表更新出错了,或者数据有问题,你可以用RollBack()方法在取消之前的相关性操作,
如果没有错,那就使用Commit()方法提交你的修改。
另外,在这个过程中,所有你改动的内容只对 你自己有效,别人不能知道你改了什么,
也不能对你正在改的表做修改,直到你提交之后,别人才能修改这些表,
检索出你修改过的内容。
mysql中的事务
默认的事务:一条sql语句就是一个事务 默认就开启事务并提交事务
手动事务:
1)显示的开启一个事务:start transaction
2)事务提交:commit代表从开启事务到事务提交 中间的所有的sql都认为有效 真正的更新数据库
3)事务的回滚:rollback 代表事务的回滚 从开启事务到事务回滚 中间的所有的
sql操作都认为无效数据库没有被更新
(二)四大特性(ACID)
1)原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
2)一致性(Consistency)
一个事务中,事务前后数据的完整性必须保持一致。
3)隔离性(Isolation)
多个事务,事务的隔离性是指多个用户并发访问数据库时, 一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。
4)持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变 就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
(三)四大隔离级别以及带来的问题
四大隔离级别
注意:INNODB默认隔离级别为repeatable read):
READ UNCOMMITTED(读未提交)
读未提交,其隔离级别最低,允许脏读。换句话说就是,如果一个事务正在处理某一数据,并对其进行了更新,但是同时没有提交事务,允许另一个事务也可以访问
READ COMMITTED(读已提交)
读已提交,和读未提交的区别就是。读未提交可以读取到别人没有提交的数据,但是读已提交只能读取到别人提交后的值,事务进行的中间值不会读取到
REPEATABLE READ(可重复读)
可重复读,简单来说就是事务处理过程中多次读取同一个数据的时候,这个值不会发生改变,其值都和第一次查询到的数据是一致的
SERIALIZABLE(可序列化)
串行化,是最严格的隔离级别,他要求所有的事务都被串行执行,既事务只能一个接一个的进行处理,不能并发执行。
带来的四种问题以及解决办法
1. 脏读(读取未提交的数据)
A事务读取B事务还未提交的数据,
此时B事务因某些原因回滚,
那么A读到的这个数据就是脏读。
用我们生活中最喜欢的东西来举例
对象 | A | B |
---|---|---|
1 | 开始事务 | |
2 | 查询余额1000元 | |
3 | 取款200元,余额变为800元 | |
4 | 开始事务 | |
5 | 查询余额800元(脏读) | |
6 | 存款1000,余额变为1800 | |
7 | 取款出错,回滚,余额变为1000 | |
8 | 提交事务 | |
备注 | 正常逻辑,余额应该是2000元。这里产生了脏读 |
解决办法
可重复读
读已提交
可序列化
2.不可重复度(多次读取,数据不一样)
是指一个事务内2次读取同一个数据的值不一样。
以转账为例:A事务读取余额1000元,B事务存款1000,然后A事务再次读取余额为2000元。
对象 | A | B |
---|---|---|
1 | 开始事务 | |
2 | 查询余额1000元 | |
3 | 开启事务 | |
4 | 存款1000元,余额变为2000元。 | |
5 | 提交事务 | |
6 | 第二次查询余额2000元 | |
备注 | 通常情况下2次查询余额应该一样,但是有时候要看具体业务 |
解决办法
可重复读
可序列化
3.幻读(多次读取,数据总量不一样)
指一个事务内2次统计数据总量,值不一样。
对象 | A | B |
---|---|---|
1 | 开始事务 | |
2 | 第一次查询数据总量为1000条 | |
3 | 开启事务 | |
4 | 插入1000条数据 | |
5 | 提交事务 | |
6 | 第二次查询数据总量为2000条 |
解决方法:
可序列化
(四)总结
针对上面的并发问题,数据库支持对应的事务隔离级别,级别从低到高分别为:Read uncommitted、Read committed、Repeatable read、Serializable(√号为带来的问题 ×号为可以解决防止的问题)
事务级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncommitted 读未提交 | 存在 | 存在 | 存在 |
Read committed 读已提交 | 不存在 | 存在 | 存在 |
Repeatable read 可重复读 | 不存在 | 不存在 | 存在 |
Serializable 可序列化 | 不存在 | 不存在 | 不存在 |