谈谈mysql中事务的实现原理

缘起

你是否还记得,我们在spring中是如何使用声明式事务的呢?没错,只需要如下一行简单的代码

@Transactional(value="transactionManager", rollbackFor = Exception.class)

那么你有没有想过,为什么只需要加这样一个注解,就能实现事务的管理呢?其背后的作用原理是怎样的呢?

spring中加@Transactional注解就能实现事务的原因浅析

要知道为什么加这样一个注解,就能实现事务的管理你需要了解注解的实现的原理和AOP的实现原理。本文不是探讨spring的源码的,所以不会分析具体的实现原理,下面只列出来一个简单的原理描述。
原理:

在你执行到加了@Transaction这个方法时,你执行的这个方法已经不是你原来的那个方法了,他是spring帮我们生成的一个代理对象的方法,
如果你了解过代理模式,那么就很容易理解。这个代理方法会在我们本来的方法执行前和执行后做一些事,做什么事呢?就是在执行前开启
一个事务然后再执行后提交或者回滚事务。

那么他的开启事务和提交回滚事务是怎么做的呢?这就需要了解mysql中事务的工作工作原理。

mysql中事务的工作原理

不知道你有没有试过通过sql语句开启一个事务呢?其实是可以的,在mysql执行

START TRANSACTION;		//开启事务
COMMIT;		//提交事务
ROLLBACK;	//回滚事务

但是默认情况下mysql中的事务是会自动提交的,比如你执行如下语句

update User set name='张三' where id='1';

虽然你没有进行任何的提交操作,但是别人仍然能查询到你的张三,这是因为mysql默认帮我们提交了。
可以通过如下语句关闭mysql的自动提交

set session autocommit=0;	//其中0代表关闭,1代表启用,默认是1
show variables like '%autocommit%';	//查询目前自动提交是关闭的还是启用的,OFF代表关闭,ON代表启用

上诉只是讲述了mysql中如何通过sql开启事务,那么mysql中事务的实现原理到底是怎样的呢?
我们要知道,mysql是一个文件数据库,也就是说最终mysql中的数据是需要落地到磁盘中的某个文件的。

以下内容转至:https://blog.csdn.net/LCRxxoo/article/details/79912190

undo 日志文件

undo记录了数据在事务开始之前的值,当事务执行失败或者ROLLBACK时可以通过undo记录的值来恢复数据。例如 AA和BB的初始值分别为3,5。

A 事务开始
B 记录AA=3到undo_buf
C 修改AA=1
D 记录BB=5到undo_buf
E 修改BB=7
F 将undo_buf写到undo(磁盘)
G 将data_buf写到datafile(磁盘)
H 事务提交

通过undo可以保证原子性、稳定性和持久性
如果事务在F之前崩溃由于数据还没写入磁盘,所以数据不会被破坏。
如果事务在G之前崩溃或者回滚则可以根据undo恢复到初始状态。
数据在任务提交之前写到磁盘保证了持久性。
但是单纯使用undo保证原子性和持久性需要在事务提交之前将数据写到磁盘,浪费大量I/O。

redo/undo 日志文件

引入redo日志记录数据修改后的值,可以避免数据在事务提交之前必须写入到磁盘的需求,减少I/O。

A 事务开始
B 记录AA=3到undo_buf
C 修改AA=1 记录redo_buf
D 记录BB=5到undo_buf
E 修改BB=7 记录redo_buf
F 将redo_buf写到redo(磁盘)
G 事务提交

通过undo保证事务的原子性,redo保证持久性。
F之前崩溃由于所有数据都在内存,恢复后重新冲磁盘载入之前的数据,数据没有被破坏。
FG之间的崩溃可以使用redo来恢复。
G之前的回滚都可以使用undo来完成。

其实可以简单的认为mysql通过两个临时变量帮我们保存了修改前的值和修改后的值,如果没有问题,那么把修改后的值写入到磁盘,如果有问题就可以通过修改前的值来回滚数据。

再回过头说说spring的执行前和执行后做了什么事

基本上可以预料的是,spring在我们的方法执行前像mysql发送了两个请求

1、关闭自动提交(set session autocommit=0;)
2、开启一个事务(START TRANSACTION;)

然后在方法的执行之后再根据我们的方法是否异常发送提交或者回滚的请求,同时开启自动提交

1、提交(COMMIT)或者 回滚(ROLLBACK)
2、开启自动提交(set session autocommit=1;)
发布了114 篇原创文章 · 获赞 146 · 访问量 35万+

猜你喜欢

转载自blog.csdn.net/qq32933432/article/details/94966063