【问题标题】:Spring Declarative transaction management with hibernate using @Transactional使用 @Transactional 进行休眠的 Spring 声明式事务管理
【发布时间】:2013-09-13 14:22:48
【问题描述】:

我的要求是通过 5 种方法将数据保存在 5 个表中。 这 5 个方法封装在单个父方法下,并用 @Transactional 注释。

循环调用这个父方法 100 次。

约束是

  1. 即使一个方法在一次迭代中失败,也必须回滚事务。(即必须毫无例外地保存 5 个方法)并且流程应该继续进行下一次迭代。

  2. 一个迭代失败不应回滚所有其他迭代。 I.,e 在 100 次迭代中,如果第 5 次迭代失败并且所有其他迭代都成功,则应提交所有 99 次迭代的操作。

  3. 在一次迭代中成功执行完所有5个方法后提交事务即可。

问题是

  1. 如果第 5 次迭代失败,则在下一次迭代中,旧值将显示在实体中。 我在 catch 块中使用了 session.clear() 方法来避免这种情况。那是对的吗?但问题是,
    即使在下一次迭代中成功插入五个方法后,事务也会回滚。并且会话中前 4 次迭代的所有数据状态都将被清除。

我正在使用 Spring 3.2、Hibernate3、HibernateTransactionManager

【问题讨论】:

    标签: spring hibernate spring-transactions


    【解决方案1】:

    我忘记在不同的bean中编写调用者方法和调用方法。因此它正在回滚。 Spring Transaction 使用 AOP。为使用@Transactional 注释的方法创建代理。这个 bean 方法应该从另一个 bean 调用,我从 Spring documentation 得到的。

    【讨论】:

      【解决方案2】:

      您希望您的迭代彼此独立地成功或失败。您希望单个迭代的 5 个步骤中的任何一个都失败,从而使整个迭代失败并回滚相应的事务。

      很明显,您希望在对应于单个迭代的服务调用级别上具有事务边界。现在,经验法则是为每个事务分配一个 Hibernate 会话。因此,应在每次迭代开始时创建 Hibernate 会话,并在结束时处理掉。这将防止随机垃圾(例如在之前的事务中未能持久保存到数据库的实体)出现在 Hibernate 会话中。

      希望这会有所帮助。

      【讨论】:

      • 感谢您的回复。但是,我正在寻找声明性事务而不是程序性事务。我已经解决并更新了帖子..
      【解决方案3】:

      查看春季交易here 的传播级别,然后选择最适合您要求的任何内容。一个满足您需要的示例如下(您也可以将myService 标记为@Transactional),但您可能想看看其他级别。

      public void myService() {
          // call myTaskCaller as many times as you like
      }
      
      @Transactional(propagation=Propagation.REQUIRES_NEW)
      public void myTaskCaller() {
          task1();
          task2();
          task3();
          task4();
          task5();
      }
      
      private void task1(){}
      private void task2(){}
      private void task3(){}
      private void task4(){}
      private void task5(){}
      

      【讨论】:

      • 感谢您的回复。我已经添加了..重新喜欢它,请查看更新的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-16
      • 1970-01-01
      • 2011-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多