Java:如何在一个请求中处理多个Hibernate事务?

时间:2016-07-27 22:53:17

标签: java spring hibernate transactions

我不确定在哪里打开我的Transaction对象。在服务层内?还是控制器层?

我的Controller基本上有两项服务,我们称之为AServiceBService。然后我的代码就像:

public class Controller {
    public AService aService = new AService();
    public BService bService = new BService();

    public void doSomething(SomeData data) {
        //Transaction transaction = HibernateUtil.getSession().openTransaction();
        if (data.getSomeCondition()) {
            aService.save(data.getSomeVar1());
            bService.save(data.getSomeVar2());
        }
        else {
            bService.save(data.getSomeVar2());
        }


        //transaction.commit(); or optional try-catch with rollback 
    }
}

我想要的行为是,如果bService#save失败,那么我可以调用transaction#rollback,以便在aService中保存的内容也会被回滚。如果我为两次保存创建一个单独的事务,这似乎是可能的。

但从另一个角度来看,我的Controller依赖Transaction看起来真的很难看。如果我在各自的服务中创建Transaction会更好(比如Spring @Transactional的工作方式),但如果我这样做,那么我不知道如何实现我想要发生的事情...

编辑:固定代码,添加了另一个条件。我没有使用任何Spring依赖项,因此使用@Transactional是不可能的。

1 个答案:

答案 0 :(得分:3)

您可以通过另一层抽象和使用构图来完成您所要求的内容。

public class CompositeABService {
  @Autowired
  private AService aservice;
  @Autowired
  private BService bservice;

  @Transactional
  public void save(Object value1, Object value2) {
    aservice.save( value1 );
    bservice.save( value2 );
  }
}

public class AService {
  @Transactional
  public void save(Object value) {
    // joins an existing transaction if one exists, creates a new one otherwise.
  }
}

public class BService {
  @Transactional
  public void save(Object value) {
    // joins an existing transaction if one exists, creates a new one otherwise.
  }
}

当您需要与多个存储库作为单个工作单元(例如事务)的一部分进行交互时,通常会使用相同的模式。

现在你的所有控制器都需要依赖CompositeABService或你想要命名的任何东西。