理论大多引自《高性能MySQL》一书,不过在自测的过程中不知道是不是SQL版本的问题,还是操作有问题,在设置事务隔离级别的时候 按书上讲SET TRANSACTION ISOLATION LEVEL 这样设置并没有实现

代码实现事务回滚,基于spring boot
1、将MySQL的自动提交关掉(不是必须的)。

SET SESSION autocommit=0; 只对当前会话生效
SET autocommit = 0; 只对本次连接生效,当断开本次与MySQL的连接,则又回到默认的自动提交模式
SET GLOBAL autocommit = 0 更改系统变量,但是如果MySQL重启则又回到默认的自动提交模式

修改配置文件永久生效
修改etc/my.cnf 文件
在[mysqld]下添加如下,记得重启。
autocommit=0

2、添加依赖

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

3、在启动类上添加注解

@EnableTransactionManagement

4、在service层添加注解(加在类名上对该类下所有方法生效,加在方法上只对该方法生效),对抛出的任何异常都进行自动回滚

	@Transactional(rollbackFor = Exception.class)
public boolean insertBook() {
int i = 0;
i += bookMapper.insertBook();
i += bookMapper.insertUser();
if (i == 2) {
return true;
} else {
return false;
}
}

对于回滚失败的问题,整理以下问题

(1)MySQL默认存储引擎是InnoDB是支持事务的,你可能采用了不支持事务的引擎。
(2)如果异常被try{} catch{}了,你自己把异常处理了spring就不回滚了,如果想让事务回滚,必须手动再抛出异常,或者手动回滚

	TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

(3)如果try-catch语句在finally中进行了return操作,那么catch中手动抛出的异常也会被覆盖,同样不会自动回滚

	@Transactional(rollbackFor = Exception.class)
public boolean insertBook() {
int i = 0;
i += bookMapper.insertBook(); try {
i += bookMapper.insertUser();
} catch (Exception e) {
throw new Exception();
} finally {
return true;
}
//TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
/* if (i == 2) {
return true;
} else {
return false;
}*/
}

(4)两个方法A和B,A方法调用了B方法,A没有设置事务,B设置了,此时对于A来讲也不会发生回滚
(5)标记@Transactional的方法必须是public 其他类型都不会开启事务
(6)如果用到了shiro框架,需要对ShrioRealm中注入的service 加注解 @Lazy或者直接调用mapper,否则对该service层事务也是不起作用的

事务简介

事务就是一组原子性的SQL查询,简单说就是开启事务后,你所执行的一组SQL语句,如果其中有任何一条语句
因为崩溃或其他原因执行失败,那么所有语句都不会执行。要么全部执行成功,要么全部失败。 开启事务
START TRANSACTION;或者BEGIN;
开启事务后要么使用 COMMIT 提交事务将修改的数据持久保留,要么使用ROLLBACK回滚所有的修改 格式如下:
START TRANSACTION;
-- BEGIN;
SELECT * FROM booktype;
UPDATE booktype SET bookTypeName = '计算机类' WHERE id = 1
-- ROLLBACK;
COMMIT;

单纯的事务概念并不是故事的全部,如果在事务执行过程中因为服务器崩溃怎么办?所以一个运行良好的事务处理系统必须满足ACID标准。

原子性(atomicity)
一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分。这就是事务的原子性。

一致性(consistency)
数据库总是从一个一致性状态转换到另一个一致性的状态。只要事务最终没有提交,事务中所作的修改也不会保存到数据库中。

隔离性(isolation)
简单来说就是一个事务所作的修改在最终提交前,对其他事务是不可见的。

持久性(durability)
一旦事务提交,则其所作的修改就会永久保存到数据库中,此时即使系统崩溃,修改的数据也不会丢失。持久性是个有点模糊的概念,因为实际上持久性也分很多不同的级别。有些持久性策略能够提供非常强的安全保障,而有些则未必。而且不可能有做到100%持久性保证的策略(如果数据库本身就能做到真正的持久性,那么备份又怎么能增加持久性呢?)

1、事务四种隔离级别
READ UNCOMMITTED(读未提交)
事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为脏读(Dirty Read)。实际应用中很少使用。

READ COMMITTED(读已提交)
一个事务开始时,只能看到已经提交的事务所作的修改。换句话说,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。这个级别也叫做不可重复读,因为两次执行同样的查询,可能会得到不一样的结果。

REPEATABLE READ(可重复读)
MySQL默认的事务隔离级别。解决了脏读的问题。该级别保证了在同一个事务中多次读取同样记录的结果是一致的。但是理论上,可重复读还是无法解决另外一个幻读的问题。所谓幻读,指的是当某个事务再次读取某个范围的数据时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。MySQL默认的存储引擎是InnoDB,通过多版本并发控制解决了幻读的问题。

SERIALIZABLE(可串行化)
事务隔离级别的最高级别,它通过强制事务串行执行,避免了前面说的幻读的问题。简单说就是SERIALIZABLE会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁的争用问题。实际开发中也很少用这个隔离级别。

MySQL查询当前系统的隔离级别
SHOW GLOBAL VARIABLES LIKE ‘%ISOLATION%’;
查询当前会话的隔离级别:SELECT @@tx_isolation;
MySQL可以通过SET GLOBAL TRANSACTION ISOLATION LEVEL 命令来设置系统隔离级别。新的隔离级别会在下一个事务中开始时生效。可以在配置文件中设置整个数据库的隔离级别,也可以指该表当前会话的隔离级别:SET SESSION TRANSACTION ISOLATION LEVEL

配置文件修改隔离级别
在mysql配置文件my.cnf中[mysqld]段下加上transaction-isolation=Read-Committed
然后重启

2、死锁
死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶行循环的现象。当多个事务试图以不同的顺序锁定资源时,就可能会产生死锁。多个事务同时锁定同一个资源时,也会产生死锁。

MySQL默认的存储引擎InnoDB目前处理死锁的方法是,将持有最少行级排他锁的事务进行回滚(这是相对比较简单的死锁回滚算法)。

死锁发生以后,只有部分或者完全回滚其中一个事务,才能打破死锁。大多数情况下只需要重新执行因死锁回滚的事务即可。

3、MySQL中的事务
MySQL默认采用自动提交的模式(AUTOCOMMIT)。也就是说如果不是显示的开始一个事务,则每个查询都被当作一个 事务执行提交操作。在当前连接中,可以通过设置AUTOCOMMIT变量来启用或者禁用自动提交模式。
SHOW VARIABLES LIKE AUTOCOMMIT

SET AUTOCOMMIT= 1;
1或ON表示启用,0或OFF表示禁用。
当 AUTOCOMMIT= 0时,所有的查询都是在一个事务中,知道显式的执行COMMIT提交或者ROLLBACK回滚,该事务结束,同时又开始了另一个新事务。修改AUTOCOMMIT对非事务型的表,如MyISAM或者内存表,不会有任何影响。对这类表来说,没有COMMIT或者ROLLBACK的概念,也可以说是相当于一直处于AUTOCOMMIT启用的模式。

另外还有一些命令,在执行之前会强制执行COMMIT提交当前的活动事务。典型的在数据定义语言(DDL)中,如果是会导致大量数据改变的操作,比如ALTER TABLE就是如此。

InnoDB采用的是两阶段锁定协议

在事务执行过程中,随时都可以执行锁定,锁只有在执行COMMIT或者ROLLBACK的时候才会释放,并且所有的锁是在同一时刻被释放。前面描述的都是隐式锁定,InnoDB会根据隔离级别在需要的时候自动枷锁。如果应用需要用到事务,还是应该选择事务型存储引擎。

MySQL事务理论及实现的更多相关文章

  1. MYSQL事务及存储引擎对比

    Innodb支持事务,而myisam不支持事务. 事务的定义: 当多个用户访问同一份数据时,一个用户在更改数据的过程中可能有其他用户同时发起更改请求,为保证数据的更新从一个一致性状态变更为另一个一致性 ...

  2. MySQL事务原理&实战【官方精译】

    事务隔离级别 事务隔离是数据库处理的基础之一.隔离是I中的首字母 ACID ; 隔离级别是在多个事务同时进行更改和执行查询时,对结果的性能和可靠性,一致性和可重复性之间的平衡进行微调的设置. Inno ...

  3. Mysql事务及锁

    一.事务(Transaction)及其ACID属性 事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性:1.原子性(Atomicity):事务是一个原子操作单 ...

  4. MySQL事务实现原理

    MySQL事务隔离级别的实现原理 知识储备 只有InnoDB支持事务,所以这里说的事务隔离级别是指InnoDB下的事务隔离级别 隔离级别 读未提交:一个事务可以读取到另一个事务未提交的修改.这会带来脏 ...

  5. 关于mysql事务行锁for update实现写锁的功能

    关于mysql事务行锁for update实现写锁的功能 读后感:用切面编程的理论来讲,数据库的锁对于业务来说是透明的.spring的事务管理代码,业务逻辑代码,表锁,应该是三个不同的设计层面. 在电 ...

  6. 超干货!为了让你彻底弄懂MySQL事务日志,我通宵肝出了这份图解!

    还记得刚上研究生的时候,导师常挂在嘴边的一句话,"科研的基础不过就是数据而已."如今看来,无论是人文社科,还是自然科学,或许都可在一定程度上看作是数据的科学. 倘若剥开研究领域的外 ...

  7. 熬夜肝出5大点,18张图带你彻底弄懂MySQL事务日志

    在当今社会,充斥着大量的数据.从众多APP上的账户资料到银行信用体系等个人档案,都离不开对大量数据的组织.存储和管理.而这,便是数据库存在的目的和价值.目前数据库的类型主要分为两种,一种是关系型数据库 ...

  8. Mysql 事务隔离级别和锁的关系

    我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所以对于 ...

  9. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

  10. MySQL 事务

    MySQL 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成 ...

随机推荐

  1. 栈—顺序栈(C实现)

    // Code file created by C Code Develop // 顺序栈 #include "ccd.h" #include "stdio.h" ...

  2. WrodPress基础之前期7个必要的基本设置

    不管使用宝塔面板搭建WordPress还是1Panel面板的方式,一个新WordPress网站需要做一些基本设置才能正式的去设计页面,填充网站内容. 1. 确保网站勾选"建议搜索引擎不收录& ...

  3. Fiddler使用界面介绍-底部状态栏

    底部状态栏 1.Capturing抓包状态 Capturing:Fiddler正在抓包 空白:Fiddler停止抓包 2.All Processes抓取进程类型 All Processes:抓取所有进 ...

  4. jdk命令行工具系列——检视阅读

    jdk命令行工具系列--检视阅读 参考 java虚拟机系列 RednaxelaFX知乎问答 RednaxelaFX博客 jps--虚拟机进程状态工具 jps :(JVM Process Status ...

  5. 通用人工智能的基石 —— 人工智能“新基建、关键基础设施”—— 3D游戏引擎

    相关: https://www.unrealengine.com/zh-CN/uses/simulation https://www.epicgames.com/site/zh-CN/careers/ ...

  6. Ubuntu的性能模式与省电模式:进行科学计算时一定要手动将Ubuntu的CPU模式设置为性能模式

    不论是什么系统,windows11还是Ubuntu.Centos.RedHat,其运行时都有一个运行模式的概念,其实这个运行模式就是CPU的性能模式,一般可以分为性能模式和省电模式两种,当然也有介于两 ...

  7. 如何使用工具下载B站非会员视频(下载B站免费web视频)

    最近准备从B站上下载几个web页面上的视频,但是B站的视频又没有提供相关的下载工具,于是找到了一款下载B站视频的工具( you-get ), 该工具不能下载会员版的视频,不能下载收费的视频,不过对于免 ...

  8. C# 工厂模式 个人基本流程

    有个前提 本文并不会介绍工厂模式,只是记录在实际当中个人比较喜欢的工厂写法.仅仅作为备忘和参考. 开始流程 定义一个抽象类,包含一些公共的业务逻辑(也可以是接口) /// <summary> ...

  9. MySQL8服务无法启动,服务没有报告任何错误

    MySQL8服务无法启动,服务没有报告任何错误 错误信息: 免安装版mysql-8.0.15-winx64.zip 按照教程来安装,解压,增加my.ini文件,修改文件内部的地址信息,配置环境变量pa ...

  10. RabbitMq高级特性之延迟队列 通俗易懂 超详细 【内含案例】

    RabbitMq高级特性之延迟队列 介绍 消息进入队列后不能立即被消费,到达指定时间后才可被消费 实现 结合以下两种即可达到延迟队列 RabbitMq高级特性之TTL过期时间 RabbitMq高级特性 ...