新事务是否会分离以前的所有实体?

时间:2013-04-27 06:28:29

标签: java spring jpa transactions ejb

假设我们有以下代码:

@Entity
public class User {
    @Id
    private String name;
    @OneToOne(cascade = CascadeType.ALL)
    private Address address;
    //getters and setters
}

@Entity
public class Address {
    @Id
    private int id;
    private String street;
    //getters and setters
}

@Stateless
//@Service
public class UserLogicClass {
    @PersistenceContext
    //@Autowired
    private EntityManager entityManager;

    public void logicOnUser(User user) {
        if(logicOnAddress(user.getAddress()) {
            otherLogicOnUser(user);
        }
    }

    public boolean logicOnAddress(Address address) {
        //
        entityManager.find(address);//address becomes managed
        //
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    //@Transactional(propagation = Propagation.REQUIRES_NEW)
    public void otherLogicOnUser
    //
        entityManager.find(user);/*without annotation, user is not managed and address is managed, but with the transaction annotation is the address still managed?*/
    //
    }
}

问题依赖于上一种方法的评论;我很好奇在Spring案例和EJB案例中都会发生什么。假设Spring配置了JTA事务,并且从此类调用的任何方法都将启动一个新事务,就像在EJB中一样。

2 个答案:

答案 0 :(得分:5)

这更像是JPA的一个问题。除非您将其扩展,否则entityManager不会传播到新事务:

@PersistenceContext(type = PersistenceContextType.EXTENDED)
//@Autowired
private EntityManager entityManager;

引用JPA 2.0规范:

  

容器管理的持久化上下文可以定义为具有   限定为单个事务或扩展的生命周期   跨越多个事务的生命周期,具体取决于   PersistenceContextType,在其实体管理器时指定   创建。本规范将此类持久性上下文称为   事务范围的持久化上下文和扩展的持久性   上下文。

答案 1 :(得分:4)

  

注意:由于此机制基于代理,因此只有“外部”方法   通过代理进入的电话将被截获。这意味着   '自调用',即目标对象中调用某些方法的方法   目标对象的其他方法,不会导致实际的事务   在运行时,即使调用的方法标有@Transactional!

在目标对象内调用otherLogicOnUser()。

了解详情:EJB Transactions in local method-calls