使用@Transactional使用hibernate进行Spring声明式事务管理

时间:2013-09-13 14:22:49

标签: spring hibernate spring-transactions

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

我在循环中调用此父方法100次。

约束

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

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

  3. 如果在一次迭代中成功执行所有5种方法后提交了事务,则可以。

  4. 问题是

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

3 个答案:

答案 0 :(得分:1)

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

获得了这个bean

答案 1 :(得分:0)

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

很明显,您希望在与单个迭代对应的服务调用级别具有事务边界。现在,拇指的规则是为每个事务分配一个Hibernate会话。因此,应该在每次迭代开始时创建一个Hibernate会话,并在最后处理它。这样可以防止随机垃圾(例如在之前的转换中未能持久保存到数据库中的ent)在Hibernate会话中显示出来。

希望这有帮助。

答案 2 :(得分:0)

查看春季交易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(){}