博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring事务管理中@Transactional
阅读量:5340 次
发布时间:2019-06-15

本文共 3394 字,大约阅读时间需要 11 分钟。

最近写的一个消息推送的接口,供订单生成后调用,发现每次传过来的时候订单id是存在的,可是利用订单id去查订单信息做后续操作时发现查不到数据,最终发现是订单生成时候业务处理写在service层,加了Spring的事务处理的相关参数:

@Transactional(value="txManager",isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,rollbackFor={Exception.class})

而紧接着消息推送的接口里也同样加了Spring的事务处理,导致上一事务未结束得不到返回的数据,这里小结下Spring的事务处理:

当一个业务活动跨越多个事务,每个事务的传播级别配置不一样。对于这个个问题,涉及到事务的传播级别,定义如下:

PROPAGATION_REQUIRED-- 如果当前没有事务,就新建一个事务。这是最常见的选择。 
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
orderDetailLs = new ArrayList
(); /** * 中间业务处理省略 */ 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
noticeLs = new ArrayList
(); List
noticeDtLs = new ArrayList
(); // 只针对好机会的订单处理 List
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;    }

问题得以解决。

 


 

详见:

 

 

转载于:https://www.cnblogs.com/xingele0917/p/3821094.html

你可能感兴趣的文章
字典常用方法
查看>>
Spring Cloud Stream消费失败后的处理策略(三):使用DLQ队列(RabbitMQ)
查看>>
bzoj1048 [HAOI2007]分割矩阵
查看>>
Java中的编码
查看>>
PKUWC2018 5/6
查看>>
As-If-Serial 理解
查看>>
洛谷P1005 矩阵取数游戏
查看>>
在Silverlight中使用HierarchicalDataTemplate为TreeView实现递归树状结构
查看>>
无线通信基础(一):无线网络演进
查看>>
如何在工作中快速成长?阿里资深架构师给工程师的10个简单技巧
查看>>
WebSocket 时时双向数据,前后端(聊天室)
查看>>
关于python中带下划线的变量和函数 的意义
查看>>
linux清空日志文件内容 (转)
查看>>
安卓第十三天笔记-服务(Service)
查看>>
Servlet接收JSP参数乱码问题解决办法
查看>>
【bzoj5016】[Snoi2017]一个简单的询问 莫队算法
查看>>
Ajax : load()
查看>>
MySQL-EXPLAIN执行计划Extra解释
查看>>
Zookeeper概述
查看>>
Zookeeper一致性级别
查看>>