首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring:事务传播

Spring:事务传播
EN

Stack Overflow用户
提问于 2017-06-20 08:34:41
回答 2查看 1.2K关注 0票数 4

我有以下代码:

代码语言:javascript
复制
@Transactional
public void handle() {
    for (Item item : getItems()) {
        handle(item);
    }
}

@Transactional(propagation = Propagation.NESTED)
public void handle(Item item) {
    /* logic here */
}

假设handle()中的循环处理10项。还假设对于3个项,handle(Item)将抛出一个异常。

我的问题:

1外部事务是否在第10项之后提交?这意味着将提交对7个项的必要更改,并将其他3个项的任何中间更改回创建的保存点?

2 handle(Item)中的异常是否会被捕获,而不会被转发给handle()?这是@Transactional做的吗?

3此外,我还想了解以下流程在行为上的区别:

代码语言:javascript
复制
@Transactional
public void handle() {
    for (Item item : getItems()) {
        handle(item);
    }
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void handle(Item item) {
    /* logic here */
}

根据我从docs的理解,这里将启动一个新事务,并暂停活动事务。这与NESTED不同,后者创建了保存点,而当前事务仍在使用中。但我相信,在REQUIRES_NEW中,7项的更改将被提交,其他3项的任何中间更改都将被遗忘。

那么,真正的区别是什么(如果有的话)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-20 08:39:15

嵌套启动主事务的子事务。REQUIRES_NEW启动单独的事务。

如果在方法之后用REQUIRES_NEW标记一个方法,那么退出数据将保留在DB中(由单独的事务提交),不管外部事务发生了什么。

在嵌套的情况下,如果回滚外部事务,则将对更改进行回滚。

见答案这里

票数 2
EN

Stack Overflow用户

发布于 2017-06-20 09:14:19

根据我从docs的理解,这里将启动一个新事务,并暂停活动事务。

  1. 如果方法handle()和handle( item )在一个服务中,将只启动一个事务-用于第一个方法。这叫做自召唤。见:

关于事务管理的一个Spring硬事实什么是交易?.

要在句柄()中应用句柄(项)的事务处理,您应该

代码语言:javascript
复制
    @Transactional
    public void handle() {
       for (Item item : getItems()) {
         applicationContext.getBean(your service).handle(item); 
       }
    }

or use spring aspectj load time weaving for self-invocation (inside one service call one method from another)

使用Propagation.REQUIRES_NEW内部循环调用方法--这不利于性能,您可以为每个调用创建新的事务。您可以在一个方法中包装,但只处理与业务逻辑相关的异常!并非所有类型的例外

代码语言:javascript
复制
@Transactional
public void handle() {
        ..some logic
        //if you really need it
        applicationContext.getBean(your service).handleBatch(getItems());
    }
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void handleBatch(Collection items) {
    for (Item item : items) {
        applicationContext.getBean(your service).handle(item)
    }
}

public void handle(Item item) {
   try{ 
      //do operation
      }catch(.appropriate type..Exception ex){
         //log exception!!!
   }
}
  1. 关于回滚: spring在RuntimeException和Error上做回滚,但在检查的异常上没有回滚。如果您的方法抛出一些已检查的异常,则更改将被执行。要避免提交,请使用@Transactional(rollbackFor=CheckedException.class)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44647872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档