关于日志的事务机制,老师解释的很模糊?为什么要回滚?
问1:有了事务机制,我理解就是能让MySQL单线程执行?麻烦解释下事务机制和多线程并发的联系?
问2:开启事务时,图1中数据文件和undo日志本来就是一样的。关闭事务后,undo和redo日志里面的内容是否清空,如果关闭事务后不清空,下一次事务开启时,清空?
问3:提交或回滚事务,意味着事务机制关闭?
问4:图2中助教提到“假设没有进行commit或rollback,数据库会直接从对应的日志文件进行数据恢复”这句话不好理解,提交就同步redu日志,回滚就恢复undu日志(这个恢复不是多次一举吗,数据文件本来没变干嘛要恢复)。我理解就是如果对事务机制使用不当,MySQL会干蠢事,自行修改原数据文件?
问5:查询1(数据来源为数据文件)-->开启事务后undo日志拷贝原数据文件-->查询2(数据源来自首先为undo日志???)-->修改undo日志保存到redo日志文件中-->查询3(数据来源首先为redo日志)-->提交或回滚后-->查询4(数据来源为数据文件),我这么理解正确?
正在回答 回答被采纳积分+1
同学你好:
1
一个事务成功的执行,必须满足以下的条件(ACID)。
其次:每一个事务是否回滚,是判断与其他事务是否发生冲突,和多线程没有关系。
事务:
事务是一条或多条数据库操作语句的组合,具备ACID,4个特点。
原子性:要不全部成功,要不全部撤销
隔离性:事务之间相互独立,互不干扰
一致性:数据库正确地改变状态后,数据库的一致性约束没有被破坏
持久性:事务的提交结果,将持久保存在数据库中
事务会产生的问题(出现回滚现象都是违反了ACID):
1)第一类丢失更新:在没有事务隔离的情况下,两个事务都同时更新一行数据,但是第二个事务却中途失败退出, 导致对数据的两个修改都失效了。
例如:张三的工资为5000,事务A中获取工资为5000,事务B获取工资为5000,汇入100,并提交数据库,工资变为5100,随后事务A发生异常,回滚了,恢复张三的工资为5000,这样就导致事务B的更新丢失了。
2)脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
例如:张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。与此同时,事务B正在读取张三的工资,读取到张三的工资为8000。随后,事务A发生异常,而回滚了事务。张三的工资又回滚为5000。最后,事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读,实际工资仍然为5000。
3)不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
例如:在事务A中,读取到张三的工资为5000,操作没有完成,事务还没提交。与此同时,事务B把张三的工资改为8000,并提交了事务。随后,在事务A中,再次读取张三的工资,此时工资变为8000。在一个事务中前后两次读取的结果并不致,导致了不可重复读。
4)幻读:是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
例如:目前工资为5000的员工有10人,事务A读取所有工资为5000的人数为10人。此时,事务B插入一条工资也为5000的记录。这时,事务A再次读取工资为5000的员工,记录为11人。此时产生了幻读。
提醒:
不可重复读的重点是修改,同样的条件,你读取过的数据,再次读取出来发现值不一样了
幻读的重点在于新增或者删除,同样的条件,第 1 次和第 2 次读出来的记录数不一样。
事务隔离级别,解决什么问题,以及存在什么问题
(1)READ_UNCOMMITTED:这是事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。解决第一类丢失更新的问题,但是会出现脏读、不可重复读、第二类丢失更新的问题,幻读 。
(2)READ_COMMITTED:保证一个事务修改的数据提交后才能被另外一个事务读取,即另外一个事务不能读取该事务未提交的数据。解决第一类丢失更新和脏读的问题,但会出现不可重复读、第二类丢失更新的问题,幻读问题
(3)REPEATABLE_READ:保证一个事务相同条件下前后两次获取的数据是一致的解决第一类丢失更新,脏读、不可重复读、第二类丢失更新的问题,但会出幻读。
(4)SERIALIZABLE:事务被处理为顺序执行。解决所有问题。
注意:Mysql默认的事务隔离级别为repeatable_read。
后面的课程中会学习到相关的内容。
2
这两个文件(日志文件的作用就是用来记录日志信息的,删除就无法看到日志信息)的信息都会持久化到硬盘中,因此不会删除。
undo日志用于存放数据修改被修改前的值。
redo日志用于记录 数据修改后的记录。
开启一个事务后,当执行修改数据库数据时,会将修改之前的记录拷贝到undo日志,将修改后的数据信息存放在redo日志中,当觉得这个事务没有问题时,redo日志会将数据同步到数据库中。这是对数据库的一次修改操作。当事务出现异常,违反数据库的事务机制(原子性、一致性、隔离性、持久性),会将事务进行一个回滚,回滚到undo日志中的记录,再同步到数据库。
3
事务的提交以及事务出现错误,发生回滚,都意味着一个事务的结束。
4
开启一个事务后,删除一条数据时,undo日志会记录删除之前的数据信息,提交后,redo会将修改后的数据情况同步到数据库中。但是在没有提交的情况下。如果mysql服务突然发生异常,数据就会从undo日志进行·数据的恢复,这时,删除语句没有实现。就会造成数据的不一致。
5
undo日志以及redo日志是记录对数据库进行修改等操作的信息,对查询不做记录。对问题2的解释描述了整个的过程。
如果我解决了同学的问题,请采纳!学习愉快^_^。
- 参与学习 人
- 提交作业 625 份
- 解答问题 2669 个
数据库作为企业储存和管理数据的根本,掌握数据库是每个开发工程师必备的技能,本阶段带你学会用Python操作MySQL、Redis和MongoDB三大主流数据库。夯实数据库基础。
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星