MySQL事务理论及实现
理论大多引自《高性能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就是如此。
在事务执行过程中,随时都可以执行锁定,锁只有在执行COMMIT或者ROLLBACK的时候才会释放,并且所有的锁是在同一时刻被释放。前面描述的都是隐式锁定,InnoDB会根据隔离级别在需要的时候自动枷锁。如果应用需要用到事务,还是应该选择事务型存储引擎。
MySQL事务理论及实现的更多相关文章
- MYSQL事务及存储引擎对比
Innodb支持事务,而myisam不支持事务. 事务的定义: 当多个用户访问同一份数据时,一个用户在更改数据的过程中可能有其他用户同时发起更改请求,为保证数据的更新从一个一致性状态变更为另一个一致性 ...
- MySQL事务原理&实战【官方精译】
事务隔离级别 事务隔离是数据库处理的基础之一.隔离是I中的首字母 ACID ; 隔离级别是在多个事务同时进行更改和执行查询时,对结果的性能和可靠性,一致性和可重复性之间的平衡进行微调的设置. Inno ...
- Mysql事务及锁
一.事务(Transaction)及其ACID属性 事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性:1.原子性(Atomicity):事务是一个原子操作单 ...
- MySQL事务实现原理
MySQL事务隔离级别的实现原理 知识储备 只有InnoDB支持事务,所以这里说的事务隔离级别是指InnoDB下的事务隔离级别 隔离级别 读未提交:一个事务可以读取到另一个事务未提交的修改.这会带来脏 ...
- 关于mysql事务行锁for update实现写锁的功能
关于mysql事务行锁for update实现写锁的功能 读后感:用切面编程的理论来讲,数据库的锁对于业务来说是透明的.spring的事务管理代码,业务逻辑代码,表锁,应该是三个不同的设计层面. 在电 ...
- 超干货!为了让你彻底弄懂MySQL事务日志,我通宵肝出了这份图解!
还记得刚上研究生的时候,导师常挂在嘴边的一句话,"科研的基础不过就是数据而已."如今看来,无论是人文社科,还是自然科学,或许都可在一定程度上看作是数据的科学. 倘若剥开研究领域的外 ...
- 熬夜肝出5大点,18张图带你彻底弄懂MySQL事务日志
在当今社会,充斥着大量的数据.从众多APP上的账户资料到银行信用体系等个人档案,都离不开对大量数据的组织.存储和管理.而这,便是数据库存在的目的和价值.目前数据库的类型主要分为两种,一种是关系型数据库 ...
- Mysql 事务隔离级别和锁的关系
我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所以对于 ...
- Mysql事务探索及其在Django中的实践(二)
继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...
- MySQL 事务
MySQL 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成 ...
随机推荐
- .NET 中高效 Excel 解决方案 MiniExcel
前言 MiniExcel 是一个用于 .NET 平台的轻量级.高性能的库,专注于提供简单易用的 API 来处理 Excel 文件.以下是 MiniExcel 的特点总结: 轻量级与高效:MiniExc ...
- java引入es使用
引入依赖 <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>el ...
- RS485总线防雷保护方案(转)
RS485作为最为最常用的电表通讯方式之一.日常生活中雷电和静电干扰已经成为485通信总线在实际工程经常遇到的问题.故如何对芯片以及总线进行有效的保护,是摆在每一个使用者面前的一个问题.在这里,我们主 ...
- 国内外GPT哪家强?对比#ChatGPT #bard #豆包 #bing #百度文心 #星火 #通义千问
#ChatGPT(openAi) ChatGPT已经被错误调教,经常把作者和名字搞混. #豆包(字节跳动) 豆包拒绝错误调教 #百度文心(百度) #星火(科大讯飞) #通义千问 (阿里巴巴) #bar ...
- 【MySQL】Tinyint 类型问题
下发字段: `DISTRIBUTION_STATUS` tinyint(1) DEFAULT '0' COMMENT '下发状态,0未下发,1已下发,2已作废', Mybatis封装之后日志打印也确实 ...
- 【Java】Input,Output,Stream I/O流 04 对象流&序列化
对象流,序列化机制 ObjectInputStream ObjectOutputStream 序列化 对象 写入转 数据 持久化 反序列化 数据 读取转 对象 活化 - 任何实现了Serializab ...
- 【HbuilderX】解决苹果手机不能连接Win10问题
从微软商店上下载Itunes 只要这个Itunes能识别Iphone,HbuilderX也可以识别Iphone 如果之前已经装了其他来源下载的Iphone,先卸载掉,然后重启系统安装 另外: 还有一种 ...
- 【转载】 Visual Studio Code几款FTP插件使用总结
===================================================== 平时要维护类似wordpress这样的网站,然后虚拟主机又不支持远程仓的版本管理.总而言之, ...
- 亲测可用的 Linux(Ubuntu18.04下)可运行的超级玛丽奥(gym-super-mario-bros)游戏的仿真环境—————————可用于强化学习算法的游戏模拟器环境
与前文中的俄罗斯方块游戏一样都是可以用于强化学习算法的游戏模拟器,这里介绍的是超级玛丽奥(gym-super-mario-bros)游戏的仿真环境. Python库,代码地址: https://git ...
- 惠普暗影精灵2pro挑电池和电源适配器
自己几年前买的暗影2pro前几个月坏掉了,无法充电,而且偶发性掉电,经过长时间研究发现该款电脑存在挑电池和电源适配器的问题. 相关资料: https://www.chinafix.com/thread ...