Spring事务管理中@Transactional
最近写的一个消息推送的接口,供订单生成后调用,发现每次传过来的时候订单id是存在的,可是利用订单id去查订单信息做后续操作时发现查不到数据,最终发现是订单生成时候业务处理写在service层,加了Spring的事务处理的相关参数:
@Transactional(value="txManager",isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,rollbackFor={Exception.class})
而紧接着消息推送的接口里也同样加了Spring的事务处理,导致上一事务未结束得不到返回的数据,这里小结下Spring的事务处理:
当一个业务活动跨越多个事务,每个事务的传播级别配置不一样。对于这个个问题,涉及到事务的传播级别,定义如下:
PROPAGATION_SUPPORTS-- 如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY-- 如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
/**
* 营销活动生成订单 A
*
* @param recvVo
* @return
* @author xingle
* @data 2014-6-9 下午5:39:10
*/
@Override
@Transactional(value="txManager",isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,rollbackFor={Exception.class})
public synchronized CreatOrderByActyRetnVo creatOrder(BigDecimal userId,
CreatOrderByActyRecvVo recvVo) { // 主订单id
BigDecimal order_id = orderDao.getOrderId();
OrderInfoVo orderInfoVo = new OrderInfoVo();
List<OrderDetailVo> orderDetailLs = new ArrayList<OrderDetailVo>();
/**
* 中间业务处理省略
*/
int m = purchaseDao.createOrderInfo(orderInfoVo);
int n = purchaseDao.createOrderDetail(orderDetailLs);
//消息推送接口
pushNoticeService.pushNotice(order_id, "01");
return vo;
}
/**
* app端消息推送 B
* @Description:
* @param order_id
* @param type
* @author xingle
* @data 2014-7-4 上午11:31:34
*/
@Override
@Transactional(value = "txManager", isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = { Exception.class })
public void pushNotice(BigDecimal order_id, String type) {
List<appNoticeVo> noticeLs = new ArrayList<appNoticeVo>();
List<appNoticeDetailVo> noticeDtLs = new ArrayList<appNoticeDetailVo>();
// 只针对好机会的订单处理
List<noticeOrderVo> orderLs = pushNoticeDao.getOrderInfo(order_id);
/**
* 中间业务处理省略
*/
pushNoticeDao.insertAppNotice(noticeLs);
pushNoticeDao.insertAppNoticeDetail(noticeDtLs);
}
}
如上,这里把creatOrder的方法称作A,pushNotice的方法称作B,A中调用B。A的事务传播性设为Propagation.REQUIRED,B的事务传播性也设为Propagation.REQUIRED,B中会沿用之前的事务继续,但是由于是在同一事务下,如果方法 B中的操作出错,比如在方法pushNoticeDao.insertAppNotice(noticeLs) 中写错语句,那么发现方法A也会失败,这和我们的要求不符。
为了不影响原订单创建,这里把B传播性设为propagation = Propagation.REQUIRES_NEW,这样B出错并不会导致A也失败,但又出现一个新的问题,即B中
:orderLs = pushNoticeDao.getOrderInfo(order_id) 列表查询不到结果,原来在同一个service下,上一方法还未提交结束。
为了解决这一问题,故把B的调用放在action层中A方法完成之后,如下:
    @Description("营销活动生成订单")
    @RequestMapping(value = "/creatOrder", method = { RequestMethod.POST })
    public @ResponseBody CreatOrderByActyRetnVo creatOrder(HttpServletRequest request, HttpServletResponse response,
        @RequestBody CreatOrderByActyRecvVo recvVo) {
        CreatOrderByActyRetnVo vo = activityService.creatOrder(userId,
                recvVo);
        try {
            pushNoticeService.pushNotice(new BigDecimal(vo.getOrderId()),
                    "01");
        } catch (Exception e) {
            logger.debug("app端消息推送写入异常", e);
        }
        return vo;
    }
问题得以解决。
Spring事务管理中@Transactional的更多相关文章
- ThreadLocal在Spring事务管理中的应用
		
ThreadLocal是用来处理多线程并发问题的一种解决方案.ThreadLocal是的作用是提供线程的局部变量,在多线程并发环境下,提供了与其他线程隔离的局部变量.通常这样的设计的情况是因为这个局部 ...
 - Spring事务管理中的配置文件(三)
		
在开发中,遇到了sql语句报错,但是并没有回滚的情况. 经过几天的排查,终于找到了事务没有回滚的原因. 原来的项目用的是informix的数据库,原来针对事务回滚的机制都是好用的.我本地用的是mysq ...
 - Spring事务管理——其他的事务属性
		
之前我们说过Spring事务管理中的事务的传播行为的属性.下面我们来说一下它的其他属性. 一.事务的隔离级别 1 .数据库事务并发问题.假设现在有两个事务:Transaction01和Transact ...
 - spring事务管理及相关知识
		
最近在项目中遇到了spring事务的注解及相关知识,突然间感觉自己对于这部分知识只停留在表面的理解层次上,于是乎花些时间上网搜索了一些文章,以及对于源码的解读,整理如下: 一.既然谈到事务,那就先搞清 ...
 - Spring事务管理——回滚(rollback-for)控制
		
探讨Spring事务控制中,异常触发事务回滚原理.文章进行了6种情况下的Spring事务是否回滚. 以下代码都是基于Spring与Mybatis整合,使用Spring声明式事务配置事务方法. 1.不捕 ...
 - 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
		
一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...
 - 事务管理(下) 配置spring事务管理的几种方式(声明式事务)
		
配置spring事务管理的几种方式(声明式事务) 概要: Spring对编程式事务的支持与EJB有很大的区别.不像EJB和Java事务API(Java Transaction API, JTA)耦合在 ...
 - Spring事务管理(转)
		
1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是 ...
 - [Spring框架]Spring 事务管理基础入门总结.
		
前言:在之前的博客中已经说过了数据库的事务, 不过那里面更多的是说明事务的一些锁机制, 今天来说一下Spring管理事务的一些基础知识. 之前的文章: [数据库事务与锁]详解一: 彻底理解数据库事务一 ...
 - MyBatis6:MyBatis集成Spring事务管理(下篇)
		
前言 前一篇文章<MyBatis5:MyBatis集成Spring事务管理(上篇)>复习了MyBatis的基本使用以及使用Spring管理MyBatis的事务的做法,本文的目的是在这个的基 ...
 
随机推荐
- Know How To Use ID_NULL Function To Search An Object In Oracle Forms
			
ID_NULL built in function is used to determine that an object type variable is null or not null in O ...
 - GoAccess日志分析工具使用文档
			
----Sevck 2016/3/4 17:24:13 #1软件说明: GoAccess是一款开源.实时,运行在命令行终端下的web日志分析工具.该工具提供快速.多样的HTTP状态统计,可以令管理员不 ...
 - 参数(条件表)灵活配置GS01/GS02/GS03
			
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
 - Codeforces Round #261 (Div. 2) B
			
链接:http://codeforces.com/contest/459/problem/B B. Pashmak and Flowers time limit per test 1 second m ...
 - hdu 1086(计算几何入门题——计算线段交点个数)
			
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1086 You can Solve a Geometry Problem too Time Limit: 2 ...
 - Simulating a Freight robot in Gazebo
			
Installation Before installing the simulation environment, make sure your desktop is setup with a st ...
 - iBATIS sql(XML)中的大于、小于、like等符号写法
			
其实就是xml的特殊符号,因为它的配置就是xml,所以可以用下面这种写法转义 < < > > <> < ...
 - C++指针内存
			
这是一个关于C++指针的问题,思考了一下 void GetMemory(char *p, int num){ p = (char*) malloc (sizeof(char) * num); } vo ...
 - iOS - OC 数据持久化
			
1.Sandbox 沙箱 iOS 为每个应用提供了独立的文件空间,一个应用只能直接访问为本应用分配的文件目录,不可以访问其他目录,每个应用自己独立的访问空间被称为该应用的沙盒.也就是说,一个应用与文件 ...
 - andriod之摄像头驱动流程
			
camera成像原理: 景物通过镜头生产光学图像投射到sensor表面上,然后转为模拟电信号,经过数模变成数字图像信号,在经过DSP加工出来,然后在通过IO接口传输到CPU处理. 由于摄像头满足总线. ...