Mysql事务处理

什么是事务?

事务是一系列的数据库操作,他们要符合 ACID 特性,事务是数据库应用的基本单位。MySQL 事务主要用于处理操作量大,复杂度高的数据。

ACID是什么?可以详细说一下吗?

A=Atomicity:原子性,就是要么全部成功,要么全部失败。不可能只执行一部分操作。
C=Consistency:一致性,系统(数据库)总是从一个一致性的状态转移到另一个一致性的状态,不会存在中间状态。
I=Isolation:隔离性,通常来说:一个事务在完全提交之前,对其他事务是不可见的.注意前面的通常来说加了红色,意味着有例外情况。
D=Durability:持久性,一旦事务提交,那么就永远是这样子了,哪怕系统崩溃也不会影响到这个事务的结果。

MySQL中为什么要有事务回滚机制?

而在 MySQL 中,恢复机制是通过回滚日志(undo log)实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后在对数据库中的对应行进行写入。当事务已经被提交之后,就无法再次回滚了。
回滚日志作用
能够在发生错误或者用户执行 ROLLBACK 时提供回滚相关的信息。
在整个系统发生崩溃、数据库进程直接被杀死后,当用户再次启动数据库进程时,还能够立刻通过查询回滚日志将之前未完成的事务进行回滚,这也就需要回滚日志必须先于数据持久化到磁盘上,是我们需要先写日志后写数据库的主要原因。

数据库并发事务会带来哪些问题?

数据库并发事务会带来 脏读、幻读、丢弃更改、不可重复读 这四个常见问题,其中:
脏读
Mysql事务处理-LaokNas网络技术笔记
A 事务读取到了 B 事务未提交的内容,但是之后B事务满足一致性等特性而做了回滚操作,那么读取事务得到的结果就是脏数据了。
幻读:A 事务读取了一个范围的内容,而同时 B 事务在此期间插入(删除)了一条数据。造成”幻觉”。
丢弃修改:两个写事务T1 T2同时对A=0进行递增操作,结果T2覆盖T1,导致最终结果是1 而不是2,事务被覆盖
不可重复读:当设置T2事务只能读取 T1 事务已经提交的部分,T2 读取一个数据,然后T1 对该数据做了修改。如果 T2 再次读取这个数据,此时读取的结果和第一次读取的结果不同。
当设置A事务只能读取 B 事务已经提交的部分,会造成在 A 事务内的两次查询,结果竟然不一样,因为在此期间 B 事务进行了提交操作。
脏读图解:
第一个事务首先读取var变量为50,接着准备更新为100的时,并未提交,第二个事务已经读取var为100,此时第一个事务做了回滚。最终第二个事务读取的var和数据库的var不一样。
幻读图解
Mysql事务处理-LaokNas网络技术笔记
T1 读取某个范围的数据,T2 在这个范围内插入新的数据,T1 再次读取这个范围的数据,此时读取的结果和和第一次读取的结果不同。
丢弃修改图解
Mysql事务处理-LaokNas网络技术笔记
T1 和 T2 两个事务都对一个数据进行修改,T1 先修改,T2 随后修改,T2 的修改覆盖了 T1 的修改。例如:事务1读取某表中的数据A=50,事务2也读取A=50,事务1修改A=A+50,事务2也修改A=A+50,最终结果A=100,事务1的修改被丢失。
不可重复读图解
Mysql事务处理-LaokNas网络技术笔记
T2 读取一个数据,T1 对该数据做了修改。如果 T2 再次读取这个数据,此时读取的结果和第一次读取的结果不同。

怎么解决这些问题呢?MySQL 的事务隔离级别了解吗?

MySQL 的四种隔离级别如下:
未提交读(READ UNCOMMITTED):事务中发生了修改,即使没有提交,其他事务也是可见的,比如对于一个数A原来50修改为100,但是我还没有提交修改,另一个事务看到这个修改,而这个时候原事务发生了回滚,这时候A还是50,但是另一个事务看到的A是100.可能会导致脏读、幻读或不可重复读。
已提交读(READ COMMITTED):对于一个事务从开始直到提交之前,所做的任何修改是其他事务不可见的,举例就是对于一个数A原来是50,然后提交修改成100,这个时候另一个事务在A提交修改之前,读取的A是50,刚读取完,A就被修改成100,这个时候另一个事务再进行读取发现A就突然变成100了;可以阻止脏读,但是幻读或不可重复读仍有可能发生。
可重复读(REPEATABLE READ):就是对一个记录读取多次的记录是相同的,比如对于一个数A读取的话一直是A,前后两次读取的A是一致的;可以阻止脏读和不可重复读,但幻读仍有可能发生。
可串行化(SERIALIZABLE):在并发情况下,和串行化的读取的结果是一致的,没有什么不同,比如不会发生脏读和幻读;该级别可以防止脏读、不可重复读以及幻读。
Mysql事务处理-LaokNas网络技术笔记

Innodb使用的是哪种隔离级别呢?

MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重复读)。
原因:与 SQL 标准不同的地方在于InnoDB 存储引擎在 REPEATABLE-READ(可重读)事务隔离级别 下使用的是 Next-Key Lock 锁算法 ,因此可以避免幻读的产生,这与其他数据库系统(如 SQL Server)是不同的。所以 说InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读) 已经可以完全保证事务的隔离性要 求,即达到了 SQL标准的SERIALIZABLE(可串行化)隔离级别。
InnoDB 存储引擎在分布式事务 的情况下一般会用到SERIALIZABLE(可串行化)隔离级别。

不可重复读和幻读区别是什么?可以举个例子吗?

不可重复读的重点是修改,幻读的重点在于新增或者删除。
例1(同样的条件, 你读取过的数据, 再次读取出来发现值不一样了 ):事务1中的A先生读取自己的工资为 1000的操作还没完成,事务2中的B先生就修改了A的工资为2000,导致A再读自己的工资时工资变为 2000;这就是不可重复读。
例2(同样的条件, 第1次和第2次读出来的记录数不一样 ):假某工资单表中工资大于3000的有4人,事务1读取了所有工资大于3000的人,共查到4条记录,这时事务2 又插入了一条工资大于3000的记录,事务1再次读取时查到的记 录就变为了5条,这样就导致了幻读。
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片