【问题标题】:Spring + hibernate, nested NOT_SUPPORTED transaction attributeSpring + hibernate,嵌套 NOT_SUPPORTED 事务属性
【发布时间】:2012-01-09 13:58:43
【问题描述】:
public class BusinessService {  //spring bean

  public dumpAllData(List){

    /* Complicated DB operation here
     * We dont want to be in transaction now (because of performance issues)
     */ 

    for(...){           //iterating through whole list
      **updateItem(item);**
    }

  }

  public updateItem(Entity e){
    //saves entity into DB
    //we want to be in transaction now
  }

}

弹簧配置:

<tx:advice id="txAdvice" transaction-manager="wsTransactionManager">
    <tx:attributes>           
      <tx:method name="dumpAllData" propagation="NOT_SUPPORTED" />
      <tx:method name="updateItem" propagation="REQUIRES_NEW" />
    </tx:attributes>
</tx:advice>

是否可能有嵌套的 REQUIRED_NEW 传播,该传播将从具有传播 NOT_SUPPORTED 的方法中调用?

问题是我们在 dumpAllData() 中运行了一个广泛的数据库操作(~ 100Mb),所以我们不想在事务中(否则会是性能问题)。但是我们希望在 updateItem 方法中的事务(回滚/提交)中(我们只是简单地更新实体)。

【问题讨论】:

    标签: spring nested commit spring-transactions propagation


    【解决方案1】:

    我看不出是否在事务中对性能有什么影响。您是否测量了性能差异,还是只是猜测?

    无论如何,如果你真的需要这样做,那么updateItem方法应该在另一个Spring bean中,注入到BusinessService bean中。

    确实,Spring 只能在通过代理调用 bean 方法时启动/提交事务。如果你从同一个 bean 的另一个方法调用一个 bean 方法,Spring 不能拦截调用并做它的事务管理。

    【讨论】:

    • 在单个事务中完成的大量数据库更新会给数据库带来沉重的负担(在 oracle 的情况下会产生大量的重做日志)。最好在自动提交模式下执行它们或分成更小的块。
    • 自动提交?与休眠?真是个坏主意,恕我直言。见docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/…
    • @Mrembisz:“分成小块”——是的,这就是我们的想法。我们希望一一提交小的更改。你有任何有用的例子/链接吗?谢谢
    • @JBNizet 我解释了为什么无论应用程序端使用什么 ORM/语言,大型事务也会对数据库端的性能产生影响。
    • @martin85 我想您可以改编 JB Nizet 评论中链接中的示例,并围绕交易相关行引入另一个循环。不过我对hibernate并没有真正的经验,所以你可能想把它作为另一个问题来问。
    【解决方案2】:

    如果从同一类的某个方法调用,Spring 事务基础架构不会拦截更新方法中的事务注释。更多关于 Spring 事务如何工作的理解请参考Spring Transaction

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 2011-11-01
      • 2016-09-10
      • 2014-02-07
      • 2016-07-06
      • 2023-04-03
      • 2012-05-18
      相关资源
      最近更新 更多