[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[备忘]spring通过嵌套事务的实现每条数据一个事务

上一篇:[整理]mysql事务隔离级别,小测试[4]
下一篇:[备忘]spring里druid连接池的配置

添加日期:2016/7/30 17:46:18 快速返回   返回列表 阅读1876次
比如有100条数据要处理,每条数据可能插入N个表。

现状:service开事务,出错回滚,也就说,前99条成功了,最后一条失败了,全都回滚了。

目标:每条数据开一个事务,失败了只回滚自己,其他数据该成功还成功。

大概代码:


AAAService:
@Transactional
public void excute(String start, String folder) {

    // 不要随便抓异常,异常不抛出去,事务不会回滚
    
    //读取订单数据,每次处理一个订单
    List<OldOrderData> orderList = readInfo(start, folder);
    for (OldOrderData order : orderList) {
        try {
            saveDataService.syncSingleOrder(order);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.print("error:" + order.getMains().getOrderno());
        }
    }

}




BBBService:
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void syncSingleOrder(OldOrderData oldOrder)  {
....//有异常往出抛,别catch住
}



执行时日志:
...
Suspending current transaction, creating new transaction with name
---成功了会提交Committing JDBC transaction on Connection
Resuming suspended transaction after completion of inner transaction
Suspending current transaction, creating new transaction with name
---失败了会回滚Rolling back JDBC transaction on Connection
...


要点:
(1)事务传播应该使用propagation=Propagation.REQUIRES_NEW,而不是Nested那个。
new的话,每个是独立的事务,可以自己提交回滚。
nested的,得外层控制提交回滚,具体没试验。

(2)处理每个数据的方法,要放到另外一个类里面。
如果两个方法在一个java类里,事务传播被忽略,根本不生效。spring这么设计的。

(3)方法得是public的,非public的事务也不生效。spring这么设计的。

(4)处理每个数据的方法里,不要catch异常,尽管让它出错,这样事务才会回滚。
外层可以catch每个数据的处理,抓异常,然后写日志,发信提醒等等。
这样,出错的数据不影响大局。


参考:
https://www.credera.com/blog/technology-insights/java/common-oversights-utilizing-nested-transactions-spring/
 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved