简体   繁体   English

Spring和JPA的交易

[英]Transactions with Spring and JPA

I am learning to use JPA. 我正在学习使用JPA。 And I'm a little confused. 我有点困惑。

According JPA EntityManager manages transactions. 根据JPA,EntityManager管理事务。 But a design pattern is to inject the EntityManager in DAOs. 但是一种设计模式是将EntityManager注入DAO中。 So how is possible that are different EntityManager to the same transaction? 那么,不同的EntityManager与同一个事务怎么可能呢?

This is the case I want to solve 这是我要解决的情况

I have the DAOs defined 我已经定义了DAO

@Repository
JPARepository1 {

    @PersistenceContext
    protected EntityManager em;

    ....   

.

@Repository
JPARepository2 {

    @PersistenceContext
    protected EntityManager em;

    ....

I have a Service 我有服务

@Service
public class ServiceImpl1 {

    @Autowired
    private JPARepository1 repo1;

    @Autowired
    private JPARepository2 repo2;  


    public void mainMethod(){
        Object o= transactionalMethod1();

        try{
            transactionalMethod2(o);
        }catch (Exception e){
            transactionalMethod3(o);
        }

    }

    private Object transactionalMethod1(){
        ....
    }

    private void transactionalMethod2(Object o){
        ....
    }


    private void transactionalMethod3(Object o){
        ....
    }

Then from @Controller I will invoke mainMethod(). 然后从@Controller我将调用mainMethod()。 What would be the right way to do transactional to transactionalMethod1, transactionalMethod2 and transactionalMethod3,within the same Service and using the same Repository's. 什么是在同一服务中并使用相同存储库对transactionalMethod1,transactionalMethod2和transactionalMethod3进行事务处理的正确方法。 I would like it if there is an exeption in transactionalMethod2, this abort the transaction, but keep the transactions of transactionalMethod1 and transactionalMethod3 Thanks, sorry for my English 我想在transactionalMethod2中有一个例外,这会中止交易,但是保留transactionalMethod1和transactionalMethod3的交易,谢谢,对不起我的英语

Usually you configure one EntityManager, so the wired manager is always the same, the one you configured. 通常,您配置一个EntityManager,所以有线管理器始终与您配置的相同。 The instance of this manager though, is different in every wiring. 但是,此管理器的实例在每次布线中都不同。

So, every transaction in your service uses a different instance of the EntityManager and thus every transaction invoked is seperated from each other. 因此,服务中的每个事务都使用EntityManager的不同实例,因此,所调用的每个事务都是相互独立的。

As so, an exception in transactionalMethod2 doesn't necessarily affects the transactionalMethod1 and transactionalMethod3 因此, transactionalMethod2中的异常不一定会影响transactionalMethod1transactionalMethod3

What would be the right way to do transactional to transactionalMethod1, transactionalMethod2 and transactionalMethod3,within the same Service and using the same Repository's. 什么是在同一服务中并使用相同存储库对transactionalMethod1,transactionalMethod2和transactionalMethod3进行事务处理的正确方法。

Now, you have two options to do service methods transactions 现在,您有两个选择可以进行服务方法transactions

1) You could annotate your whole @Service like that: 1)您可以像这样注释整个@Service

@Service
@Transactional
public class ServiceImpl1 {
....

so every method declared here is also a transaction . 所以这里声明的每个方法也是一个事务

2) You could annotate each method as @Transactional : 2)您可以将每个方法都注释为@Transactional

@Transactional
private Object transactionalMethod1(){
    ....
}

@Transactional
private void transactionalMethod2(Object o){
    ....
}

@Transactional
private void transactionalMethod3(Object o){
    ....
}

If you want to use a single repository just @Autowired a single one and use it in your @Transactional method. 如果要使用单个存储库,只需@Autowired单个存储库,然后在@Transactional方法中使用它。 Eg: 例如:

@Service
@Transactional
public class ServiceImpl1 {

@Autowired
private JPARepository1 repo1; 

public void mainMethod(){
    Object o= transactionalMethod1();

    try{
        transactionalMethod2(o);
    }catch (Exception e){
        transactionalMethod3(o);
    }

}

private Object transactionalMethod1(){
    return repo1.findOne();
}

private void transactionalMethod2(Object o){
    repo1.create(o);
}


private void transactionalMethod3(Object o){
    repo1.delete(o)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM