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的事务的做法,本文的目的是在这个的基 ...
随机推荐
- Writing Text File From A Tabular Block In Oracle Forms
The example given below for writing text file or CSV using Text_IO package from a tabular block in O ...
- Ubuntu下手动安装VMware Tools步骤
To mount the CD image and extract the contents: Power on the virtual machine. Log in to the virtual ...
- 解决iOS内存泄露
文章很好,摘自:http://www.codeceo.com/article/xcode-instruments-ios-memory.html 虽然iOS 5.0版本之后加入了ARC机制,由于相互引 ...
- CI实践_Android持续集成
之前已经实现了Android的持续集成,并在项目中应用了一段时间.恰逢现在有几分钟时间,把之前的一些零散的点滴记录和整理一下,供有需要的朋友参考,或后续复用. 需要的准备知识:gitlab.Jenki ...
- iOS - UIStoryboard
前言 NS_CLASS_AVAILABLE_IOS(5_0) @interface UIStoryboard : NSObject @available(iOS 5.0, *) public clas ...
- Win7_关闭休眠文件hiberfil.sys
1. C盘根目录下 hiberfil.sys 占用好几G空间,直接删 删不掉,也不推荐直接删. 2. 2.1.命令窗口中输入 powercfg -h off,即可关闭休眠功能,同时 Hiberfil. ...
- 笔记本_thinkpad_e40
1. 0578A69 2.驱动下载 相关地址 XPhttp://think.lenovo.com.cn/support/driver/detail.aspx?docID=DR1253259153348 ...
- poj2420A Star not a Tree?(模拟退火)
链接 求某一点到其它点距离和最小,求这个和,这个点 为费马点. 做法:模拟退火 #include <iostream> #include<cstdio> #include< ...
- (五)c语言条件编译#ifdef与#if defined
c语言条件编译#ifdef与#if defined defined NAME是用来判断NAME是否被定义了(被用define定义了). #ifdef NAME == #if defined(NAME) ...
- TCP/IP,Http,Socket,XMPP的区别
大学学习网络基础的时候老师讲过,网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层.通过初步的了解,我知道IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用 ...