2010-07-04 85 views
1

如果我想通过编程管理事务,就是由EntityManager的春天JPA - 注射事务管理器VS注入实体管理器

public class MyDAO { 
@PersistenceContext(unitName="test") EntityManager em; 

JpaTransactionManager txnManager = null; 
public void setTxnManager(JpaTransactionManager mgr) { 
    txnManager = mgr; 
} 

public void process(Request request) throws Exception { 
    TransactionStatus status = 
    txnManager.getTransaction(new DefaultTransactionDefinition()); 
    try { 
    em.persist(request); 
    txnManager.commit(status); 
    } catch (Exception up) { 
    txnManager.rollback(status); 
    throw up; 
    } 
} 

注入一个PlatformTransactionManager VS直接注入EntityMangerFactory/EntityManager的和获得的交易开始交易之间的差异作为并列于注入的EntityManager直接

public class MyDAO { 
    @PersistenceContext(unitName="test") 
    EntityManager em; 

    public void process(Request request) throws Exception { 
     EntityTransaction txn = em.getTransaction(); 
     try { 
     em.persist(request); 
     txn.commit(); 
     } catch (Exception up) { 
     txn.rollback(); 
     throw up; 
     } 
    } 

其中作为弹簧配置片段看起来像这样

<beans> 
    <bean id="MyDAO" class="com.xyz.app.dao.MyDAO"> 

    <context:annotation-config /> 

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerE ntityManagerFactoryBean"> 
     <property name="persistenceUnitName" value="persistence" /> 
     <property name="dataSource" ref="dataSourceProvider" /> 
     <property name="jpaVendorAdapter" ref="jpaVendorAdapter" /> 
    </bean> 

    <bean id="transactionManagerJpa" class="org.springframework.orm.jpa.JpaTransactionM anager"> 
      <property name="entityManagerFactory" ref="entityManagerFactory"/> 
    </bean> 
</beans> 

回答

4

事务管理器不应该注入到DAO中,因为DAO无法判断它们是否是大事务中的一个参与者。

我认为事务管理器属于服务层,而不是持久层。这些服务知道用例和工作单元。他们编排其他服务,DAO和模型对象来完成他们的用例。

+0

好的,我现在有两个问题 - 第一 - 如果我去声明性事务管理,然后我会注释我的方法在DAO是@Transactional权利。在这种情况下,DAO上的所有方法调用都通过Transactional代理进行路由,所以谁在这里管理事务,我认为Spring正在将事务内的每个方法调用(即资源本地)封装起来。 为什么不能以这样的方式编写DAO方法,即如果已经存在的事务可用(由于来自此DAO中事务已经开始的另一方法的调用),则使用该事务。 – Vamsi 2010-07-05 06:48:08

+1

不,您将服务方法注释为@Transactional,然后将其代理。 – duffymo 2010-07-05 13:00:53