Mysql事务结合spring管理
spring事务相关问题记录
遇到情况:
在本地单体应用调试代码时,发现在一个加了@transaction注解的方法里进行先更新后查询的操作,查询的结果是可以看到更新的内容的。而在微服务环境中同样的代码却在后查询时查不到前面更新的内容。
伪代码如下:
@Transactional
public void call() {
bidPlanMapper.updateByPrimaryKey(plan);
List<BidPlan> all = systemService.findBidPlan();
System.out.println(all);//单体应用时可观察到更改的结果
}
猜测本地可以而微服务上不可以,估计是因为微服务在执行call()方法时,update操作是由biz服务调用的,而findBidPlan()操作是实际是调用system服务进行的(该方法也有@Transactional),故产生的是两个事务。
处理办法:
- update操作后立刻提交事务,则另外一个事务可以查询到处理的结果。
@Autowired
private DataSourceTransactionManager transactionManager;
public void call() {
//开启新事务
DefaultTransactionDefinition transDefinition = new DefaultTransactionDefinition();
transDefinition.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus transStatus = transactionManager.getTransaction(transDefinition);
try {
bidPlanMapper.updateByPrimaryKey(plan);//先提交更新的操作
transactionManager.commit(transStatus);
} catch (Exception e) {
transactionManager.rollback(transStatus);
}
}
扩展阅读:
隔离级别:
隔离级别定义一个事务可能受其他并发事务活动活动影响的程度。另一种考虑一个事务的隔离级别的方式,是把它想象为那个事务对于事物处理数据的自私程度。
在一个典型的应用程序中,多个事务同时运行,经常会为了完成他们的工作而操作同一个数据。并发虽然是必需的,但是会导致以下问题:
脏读(Dirty read)-- 脏读发生在一个事务读取了被另一个事务改写但尚未提交的数据时。如果这些改变在稍后被回滚了,那么第一个事务读取的数据就会是无效的。
不可重复读(Nonrepeatable read)-- 不可重复读发生在一个事务执行相同的查询两次或两次以上,但每次查询结果都不相同时。这通常是由于另一个并发事务在两次查询之间更新了数据。(即不可重复读到同值)
幻影读(Phantom reads)-- 幻影读和不可重复读相似。当一个事务(T1)读取几行记录后,另一个并发事务(T2)插入了一些记录时,幻影读就发生了。在后来的查询中,第一个事务(T1)就会发现一些原来没有的额外记录。
| 隔离级别 | 含义 |
|---|---|
| ISOLATION_DEFAULT | 使用后端数据库默认的隔离级别。 |
| ISOLATION_READ_UNCOMMITTED | 允许读取尚未提交的更改。可能导致脏读、幻影读或不可重复读。 |
| ISOLATION_READ_COMMITTED | 允许从已经提交的并发事务读取。可防止脏读,但幻影读和不可重复读仍可能会发生。 |
| ISOLATION_REPEATABLE_READ(MySQL默认隔离级别) | 对相同字段的多次读取的结果是一致的,除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻影读仍可能发生。 |
| ISOLATION_SERIALIZABLE | 完全服从ACID的隔离级别,确保不发生脏读、不可重复读和幻影读。这在所有隔离级别中也是最慢的,因为它通常是通过完全锁定当前事务所涉及的数据表来完成的。 |
1.查看当前会话隔离级别
select @@tx_isolation;
2.查看系统当前隔离级别
select @@gobal.tx_isolation;
模拟read committed隔离级别下出现不可重复读的状况:
开启一个事务A进行三次查询。事务B在事务A第一和第二次查询中进行数据更新,事务B在事务A第二次和第三次查询中进行事务提交。
- 事务A
mysql> SET SESSION TRANSACTION ISOLATION LEVEL read committed; #设置当前会话事务的隔离级别为read committed
mysql> select @@tx_isolation; #查询当前会话事务的隔离级别
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
mysql> start transaction; #开启事务A
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t_user; #事务A第一次查询 (1)
+----+------+----------+-------+
| id | name | password | phone |
+----+------+----------+-------+
| 1 | 张三 | 123 | 000 |
+----+------+----------+-------+
###################### 事务B进行更新操作 ##############################
mysql> select * from t_user; #事务A第二次查询,没有看到事务B没有提交的更新操作。说明已经防止了脏读问题。(3)
+----+------+----------+-------+
| id | name | password | phone |
+----+------+----------+-------+
| 1 | 张三 | 123 | 000 |
+----+------+----------+-------+
###################### 事务B进行事务提交 ##############################
mysql> select * from t_user; #观察到事务B提交的结果,说明无法在同个事务中多次查询值都是一样的,即无法避免不可重复读问题。(5)
+----+------+----------+-------+
| id | name | password | phone |
+----+------+----------+-------+
| 1 | 张三 | 123 | 123 |
+----+------+----------+-------+
- 事务B
mysql> start transaction; #开启事务B
mysql> update t_user set `phone` = '123' where id = 1; #进行更新操作(2)
mysql> commit; #提交事务B (4)
理解REPEATABLE READ 隔离级别下什么是可重复读:
开启两个事务。
- 事务A
mysql> begin;
mysql> select * from t_user; #(1)
+----+------+----------+-------+
| id | name | password | phone |
+----+------+----------+-------+
| 1 | 张三 | 123 | 188 |
+----+------+----------+-------+
###################### 事务B进行事务提交 ##############################
mysql> select * from t_user; #可观察到两次查询结果都一样,不会因为事务B的更新提交而有影响(3)
+----+------+----------+-------+
| id | name | password | phone |
+----+------+----------+-------+
| 1 | 张三 | 123 | 188 |
+----+------+----------+-------+
- 事务B
mysql> begin;
mysql> update `t_user` set `phone` = '8888'; #(2)
mysql> commit; #(2)
虽然该隔离级别下是,无论事务B进行更新、新增、删除,在事务A中仍然可以重复读到相同值的。
但是如果事务A进行更新操作,则可以对事务B新增的数据进行直接更新。
可参考如下例子:
在REPEATABLE READ 隔离级别下,MySQL在session1执行UPDATE语句的时候对于session2的INSERT语句是可以看到的,也就是说发生了幻读。
相关阅读:MySQL在REPEATABLE READ 隔离级别下的工作方式

Mysql事务结合spring管理的更多相关文章
- MySQL事务及Spring事务管理
事务,是在数据库中用于保证数据正确性的一种机制,涉及到很多概念以及不同的情况,这里做一个总结 相关概念 事务四特性(ACID) 原子性(Atomicity,或称不可分割性):要么全部完成或者全部不完成 ...
- spring框架学习(六)AOP事务及spring管理事务方式之Template模板
概念 1.事务 1)事务特性:ACID 原子性 :强调事务的不可分割. 一致性 :事务的执行的前后数据的完整性保持一致. 隔离性 :一个事务执行的过程中,不应该受到其他事务的干扰. 持久性 :事务一旦 ...
- mysql事务,视图,权限管理,索引,存储引擎(胖胖老师)
1: 视图什么是视图 视图是一个虚拟表, 它的内容来源于查询的实表, 本身没有真正的数据;视图的作用 对于复杂的查询时,每次查询时都需要编写一些重复的查询代码让编写sql的效率低下, 为了 ...
- 通过案例掌握Spring 管理事务的步骤及配置
案例描述 通过完成生成订单业务,掌握事务处理. 需要d_order表和d_item表 订单生成时的业务逻辑:向d_order插入1条数据的同时,向t_item中插入若干条数据 这就是一个独立的 ...
- spring框架学习(八)spring管理事务方式之注解配置
1.DAO AccountDao.java package cn.mf.dao; public interface AccountDao { //加钱 void increaseMoney(Integ ...
- spring框架学习(七)spring管理事务方式之xml配置
1.DAO AccountDao.java package cn.mf.dao; public interface AccountDao { //加钱 void increaseMoney(Integ ...
- spring boot mysql 事务
mysql默认 事务自动提交.即:每条insert/update/delete语句,不需要程序手工提交事务,而是mysql自行提交了. 如果我们想实现程序事务提交,需要事先关闭mysql的自动提交事务 ...
- mysql事务级别和spring中应用
一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有 ...
- mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干
1.mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干 2.一般来说,事务是必须满足4个条件(ACID): Atomicity(原子性).Con ...
随机推荐
- Cassandra数据建模中最重要的事情:主键
Cassandra数据建模中要了解的最重要的事情:主键 使用关系数据建模,您可以从主键开始,但是RDBMS中的有效数据模型更多地是关于表之间的外键关系和关系约束.由于Cassandra无法使用JOIN ...
- 动态规划最短路径LintcodeNO110
动态规划最短路径LintcodeNO110 简单的dp题,没啥好说的... class Solution { public: /** * @param grid: a list of lists of ...
- Airbnb如何应用AARRR策略成为全球第一民宿平台
案例背景 基于房东和租客的痛点构建短租平台,但困于缓慢增长 2007年,住在美国旧金山的两位设计师——BrianChesky与Joe Gebbia正在为他们付不起房租而困扰.为了赚点外块,他们计划将阁 ...
- TensorFlow——TensorBoard可视化
TensorFlow提供了一个可视化工具TensorBoard,它能够将训练过程中的各种绘制数据进行展示出来,包括标量,图片,音频,计算图,数据分布,直方图等,通过网页来观察模型的结构和训练过程中各个 ...
- 一款精美的Toast第三方库的简单使用
以前一直用的安卓原生Toast,个人感觉Toast这东西,没必要花功夫,知道看到了Toasty这东西,立刻被圈粉了,真的非常好看. 项目地址 我们都知道,安卓原生Toast的用法是 Toast.mak ...
- FNScanner二维码接口openView自定义扫码Demo
本文出自APICloud官方论坛 FNScanner 模块是一个二维码/条形码扫描器,是 scanner 模块的优化升级版.在 iOS 平台上本模块底层集成了 Zbar 和系统自带的条形码/二维码分析 ...
- Jenkins Pipeline Job构建配置
1.创建pipeline job任务,新建任务>输入任务名称>选择“流水线”>点击[确定] 添加描述,This is my first test pipelin ...
- python 面向对象-初识
一.分类 1.面向过程 2.面向函数 3.面向对象 二.类和对象 1.宏关 类是抽象的,对象是具体的 2.实例化 类->对象 3.类的作用 1)实例化成对象 实例化的过程,创建self对象,调用 ...
- Linux下搭建Jmeter+Ant+Jenkins自动化测试框架
前言 在之前的文章中,我们学习了通过Ant调用Jmeter脚本生成HTML测试报告,但未实现自动执行脚本生成报告,同时生成的报告是在Linux下,查看报告很不方便.因此,我们将结合Jenkins来进一 ...
- 高通量计算框架HTCondor(二)——环境配置
目录 1. 概述 2. 安装 3. 结果 4. 相关 1. 概述 HTCondor是开源跨平台的分布式计算框架,在其官网上直接提供了源代码和Windows.Linux以及MacOS的安装包.因为平台限 ...