对Spring事务的一些误解
提起spring事务,就会让人联想起四大基本特征,五个隔离级别,七大传播特性。相信大多数人都知道这些东西,但是知道是一回事情,能用好真的是另一回事了。在使用Spring事务的时候,我曾遇到过几个比较严肃的问题,在这里我做一个自我总结。
问题一、 propagation.NESTED和propagation.REQUIRED_NEW有什么区别?
当调用方不存在事务的时候,两者的效果是一致的。所以这里讨论问题的前提是调用方存在事务。PROPAGATION_REQUIRES_NEW 启动一个新的, 不依赖于环境的 "内部" 事务. 这个事务将被完全 commited 或 rolled back 而不依赖于外部事务, 它拥有自己的隔离范围, 自己的锁, 等等. 当内部事务开始执行时, 外部事务将被挂起, 内务事务结束时, 外部事务将继续执行.
另一方面, PROPAGATION_NESTED 开始一个 "嵌套的" 事务, 它是已经存在事务的一个真正的子事务. 潜套事务开始执行时, 它将取得一个 savepoint. 如果这个嵌套事务失败, 我们将回滚到此 savepoint. 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交.
由此可见, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大区别在于, PROPAGATION_REQUIRES_NEW 完全是一个新的事务, 而 PROPAGATION_NESTED 则是外部事务的子事务, 如果外部事务 commit, 潜套事务也会被 commit, 这个规则同样适用于 roll back.
问题二、 @Transactional为什么会失效?
1.调用方和被调用方属于同一个component,被调用方的 @Transacational 注解无效
package com.transacational;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
/**
* Created by chenqimiao on 17/10/31.
*/
@Component
public class Service {
public void test1(){
test2();
}
@Transactional//此处的注解无效
public void test2(){
}
}
2.被调用方不是一个public方法,被调用方的 @Transacational 注解无效
@Component
public class Service {
@Resource
private Service1 service1;
public void test1(){
test2();
service1.test3();
}
@Transactional//1.此处的注解无效
public void test2(){
}
}
package com.transacational;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
/**
* Created by chenqimiao on 17/10/31.
*/
@Component
public class Service1 {
@Transactional//2.此处注解无效
protected void test3(){
}
}
3.未开启事务开关,如:在springboot中,启动类未使用 @EnableTransactionManagement
问题三、 如何理解@Transactional的超时时间
timeout 是一个供开发者设置超时时间的属性。默认值-1,超时时间由具体的sql系统决定。
/**
* Created by chenqimiao on 17/10/31.
*/
@Component
public class Service3 {
@Resource
private AdminInfoDoMapper adminInfoDoMapper;
@Transactional(timeout = 4)//并不会超时
public void test4(){
adminInfoDoMapper.selectNameById(1);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
超时时间具体的定义:事务开始(在该方法第一句代码执行之前)到最后一个Statement执行完毕
所以象下面这样写,事务就会超时
@Component
public class Service3 {
@Resource
private AdminInfoDoMapper adminInfoDoMapper;
@Transactional(timeout = 4)
public void test4(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
adminInfoDoMapper.selectNameById(1);
}
}
问题四、 @Transactional默认的回滚策略
默认情况下,只有当RuntimeException或其子类的异常被事务捕获之后,事务才会回滚,如果要让事务能够回滚所有异常,必须手动指定 @Transactional(rollbackFor=Exception.class) ,这样继承Exception的子类或者Exception本身都可以让事务回滚。
对Spring事务的一些误解的更多相关文章
- 【Spring】看了这篇Spring事务原理,我才知道我对Spring事务的误解有多深!
写在前面 有很多小伙伴们留言说,冰河,你能不能写一篇关于Spring事务的文章呢?我:可以啊,安排上了!那还等什么呢?走起啊!! 事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有 ...
- Spring 事务管理高级应用难点剖析--转
第 1 部分 http://www.ibm.com/search/csass/search/?q=%E4%BA%8B%E5%8A%A1&sn=dw&lang=zh&cc=CN& ...
- Spring事务传播机制
Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播,即协调已经有事务标识的方法之间的发生调用时的事务 ...
- Spring事务传播特性的浅析——事务方法嵌套调用的迷茫
Spring事务传播机制回顾 Spring事务一个被讹传很广说法是:一个事务方法不应该调用另一个事务方法,否则将产生两个事务.结果造成开发人员在设计事务方法时束手束脚,生怕一不小心就踩到地雷. 其实这 ...
- Spring 事务管理高级应用难点剖析: 第 1 部分
Spring 的事务管理是被使用得最多的功能之一,虽然 Spring 事务管理已经帮助程序员将要做的事情减到了最小.但在实际开发中,如果使用不当,依然会造成数据连接泄漏等问题.本系列以实际应用中所碰到 ...
- spring事务传播行为讲解转载
https://segmentfault.com/a/1190000013341344 前言 Spring在TransactionDefinition接口中规定了7种类型的事务传播行为.事务传播行为是 ...
- Spring事务的传播属性
前言 Spring在TransactionDefinition接口中规定了7种类型的事务传播行为.事务传播行为是Spring框架独有的事务增强特性,他不属于的事务实际提供方数据库行为.这是Spring ...
- spring事务概念理解
1.数据并发问题 脏读 A事务读取B事务尚未提交的更新数据,并在此数据的基础上操作.如果B事务回滚,则A事务读取的数据就是错误的.即读取了脏数据或者错误数据. 不可重复组 A事务先后读取了B事务提交[ ...
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...
随机推荐
- Shiro第三篇【授权、自定义reaml授权】
Shiro授权 上一篇我们已经讲解了Shiro的认证相关的知识了,现在我们来弄Shiro的授权 Shiro授权的流程和认证的流程其实是差不多的: Shiro支持的授权方式 Shiro支持的授权方式有三 ...
- Struts2第九篇【OGNL、valueStack详解】
什么是OGNL表达式? OGNL是Object Graphic Navigation Language 是操作对象属性的开源表达式. Struts2框架使用OGNL作为默认的表达式语言. 为什么我们学 ...
- mybatis-basedao的实现
package com.yangwei.shop.dao; import java.util.HashMap; import java.util.List; import java.util.Map; ...
- php-laravel4.0框架 简单快速入门
前提必须已经安装好了laravel4.0版本. 写入权限: 安装完 Laravel ,你还需要为web服务器设置 app/storage 目录的写入权限. 目录结构: 安装完框架后,你需要熟悉一下该项 ...
- struts2---自定义类型转换器
从servlet我们知道从页面获取到的参数都是string类型,但是struts2中基本的数据类型,它可以自动帮我们转化为其对应的包装类,就像获取到123,可以自动转化为Integer,但是比如201 ...
- 在分布式数据库中CAP原理CAP+BASE
本篇博文的内容均来源于网络,本人只是整理,仅供学习! 一.关系型数据库 关系型数据库遵循ACID规则 事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性: 1.A (At ...
- 第6章 Overlapped I/O, 在你身后变戏法 ---被激发的 Event 对象 -4
以文件 handle 作为激发机制,有一个明显的限制,那就是没办法说出到底是哪一个 overlapped 操作完成了.如果每个文件 handle 只有一个操作等待决定,上述问题其实并不成为问题.但是如 ...
- Integer的自动拆箱
public class Test2{ public static void main(String[] args){ Integer a=1; Integer b=2; Integer c=3; I ...
- 【转】Mapreduce部署与第三方依赖包管理
Mapreduce部署是总会涉及到第三方包依赖问题,这些第三方包配置的方式不同,会对mapreduce的部署便捷性有一些影响,有时候还会导致脚本出错.本文介绍几种常用的配置方式: 1. HADOOP_ ...
- webservice部署到服务器报错
System.Net.WebException: 基础连接已经关闭: 发送时发生错误. ---> System.IO.IOException: 从传输流收到意外的 EOF 或 0 个字节. 在 ...