2010-07-04 62 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