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 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成 ...
随机推荐
- 题解:P10733 [NOISG2019 Prelim] Lost Array
题解:P10733 [NOISG2019 Prelim] Lost Array 思路 对于任意 \(\min(X_{A_{i}},X_{B_{i}})=C_{i}\). 只要让 \(X_{A_{i}} ...
- 全网最好看的单细胞umap图绘制教程
全网最好看的单细胞umap图绘制教程 作者按 大家或许都曾被Nature, Science上的单细胞umap图吸引过,不免心生崇拜.在这里,我们将介绍一种简单方便的顶刊级umap图可视化 全文字数|预 ...
- java程序设计期末复习总结&复盘
java复习 java的特点:简单.面向对象.可移植.跨平台.分布式.多线程.稳定安全.高性能 一个数组可以存放许多不同类型的数值. (F) StringBuffer类是线程安全的,StringBui ...
- c++代码实现 RSA的简易demo【偏向实践】
写在前面 [如果你还没搞明白算法具体步骤建议先去看视频了解,本demo旨在简单实践该算法] 本实践在理论上是成立的,但由于计算x的时候很容易溢出,所以观者可以理解该简易demo后对数据进行处理[以字符 ...
- 无缝融入,即刻智能[1]:MaxKB知识库问答系统,零编码嵌入第三方业务系统,定制专属智能方案,用户满意度飙升
无缝融入,即刻智能[1]:MaxKB知识库问答系统,零编码嵌入第三方业务系统,定制专属智能方案,用户满意度飙升 1.简介 MaxKB(Max Knowledge Base)是一款基于 LLM 大语言模 ...
- 【Vue】Re06 组件化
将一个应用页面拆分成若干个可重复使用的组件 一.Vue的组件的使用步骤: 1.创建组件构造器 2.注册组件 3.使用组件 <!DOCTYPE html> <html lang=&qu ...
- DirectX9(D3D9)游戏开发:高光时刻录制和共享纹理的踩坑
共享纹理 老游戏使用directx9无法直接与cc高光sdk(d3d11)对接,但是d3d9ex有共享纹理,我们通过共享纹理把游戏画面共享给cc录制,记录一些踩坑的笔记. 共享纹理示例: // 初始化 ...
- GTC 2024 NVIDIA推出的新一代终端智能芯片 —— Jetson Thor
比较好奇,NVIDIA今年推出的终端芯片Jetson Thor到底是个啥样,毕竟这东西在机器人元年的2024年开始预热宣传,2025年大规模部署,注定是AI领域的一个重要角色. 看完GTC 2024的 ...
- 【转载】 tensorflow中的batch_norm以及tf.control_dependencies和tf.GraphKeys.UPDATE_OPS的探究
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/huitailangyz/article/ ...
- 某宝购入牙膏厂U后其售后事宜的思虑
近日某宝购入i7 9700k, 突然想去保修的问题(没有发票,要发票比京东自营贵200左右, 不要则便宜100左右),由于确实囊中幸亏所以还是选择了某宝,东西到手后突然想起这东西没票是否可以保修 ...