2010-07-01 85 views
11

我有一個小門頁,其中包含了兩個Spring管理的bean,一個是DAO,另一個是服務對象:如何以編程方式獲取線程中的事務管理器?

public class MergeAccountsPage extends WebPage 
{ 
    @SpringBean 
    private MergeEmailDao mergeEmailDao; 

    @SpringBean 
    private MergingService mergingService; 
} 

MergingService的實現的方法主要有@Transactional註釋,所以涉及MergingService作品的每一個動作精細。

但是問題就來了這裏:

Link<Void> link = new Link<Void>("cancelLink") { 
    @Override 
    public void onClick() { 
    ma.setNewEmail(null); 
    ma.setNewEmailClicked(null); 
    ma.setNewEmailSentTime(null); 
    mergeAccoungDao.update(ma); //not written to DB 
    setResponsePage(...); 
    } 
}; 

該鏈接將調用mergeAccoungDao.update(ma)在數據庫中更新行。

但是數據沒有更新到DB,我認爲這是因爲DAO沒有包裹在@Transaction中,也沒有包含tx:adviceaop標籤。

我不知道有沒有辦法以編程方式獲取交易管理器,並手動打開/關閉交易?

注:我可以在Spring的XML添加該代碼解決這個問題:

<tx:advice id="txAdviceApp" transaction-manager="transactionManagerApp"> 
    <tx:attributes> 
     <tx:method name="get*" read-only="true"/> 
     <tx:method name="save*" propagation="REQUIRED"/> 
     <tx:method name="update*" propagation="REQUIRED"/> 
     <tx:method name="delete*" propagation="REQUIRED"/> 
     <tx:method name="*" propagation="SUPPORTS"/> 
    </tx:attributes> 
    </tx:advice> 

    <aop:config> 
    <aop:pointcut id="methods" expression="execution(* destiny.utils.AbstractDao+.*(..))"/> 
    <aop:advisor advice-ref="txAdviceApp" pointcut-ref="methods"/> 
    </aop:config> 

使DAO的保存/更新/刪除會像一個魅力。

但我不想添加這個配置。因爲事實上,DAO延伸的AbstractDao的,還有其他的DB/DAO的擴展這個AbstractDao的:

public interface AbstractDao<T> { 
    public T get(Serializable id); 
    public T save(T t); 
    public T update(T t); 
    public void delete(T t); 
} 

public abstract class AbstractDaoJpaImpl<T> implements AbstractDao<T> 

public interface MergeAccountDao extends AbstractDao<MergeAccount> 

@Repository 
public class MergeAccountDaoImpl extends AbstractDaoJpaImpl<MergeAccount> implements MergeAccountDao 

因此,如果這個AbstractDao的的CRUD是這個transactionManagerApp「諫」,其他的DAO可能有問題,因爲其他DAO可能依賴於txManagerForum,txManagerBank,txManagerUser等。

回到問題,有沒有辦法以編程方式獲取txManager?如:

TransactionManager txManager = TxManagerThreadLocal.get(); 
txManager.begin(); 
ma.setNewEmailSentTime(null); 
mergeAccoungDao.update(ma); 
txManager.commit(); 

或者是否有任何更好的方法將事務包裝到DAO?

非常感謝。

回答

14

您必須將事務管理器注入要使用它的類中。您可以使用基於構造函數或屬性的注入或使用自動裝配。 你得到了事務管理器,你可以在Spring中使用編程事務支持來啓動和提交事務。下面是從春季示例代碼引用2.5:

public class SimpleService implements Service { 

    // single TransactionTemplate shared amongst all methods in this instance 
    private final TransactionTemplate transactionTemplate; 

    // use constructor-injection to supply the PlatformTransactionManager 
    public SimpleService(PlatformTransactionManager transactionManager) { 
    Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null."); 
    this.transactionTemplate = new TransactionTemplate(transactionManager); 
    } 

    public Object someServiceMethod() { 
    return transactionTemplate.execute(new TransactionCallback() { 

     // the code in this method executes in a transactional context 
     public Object doInTransaction(TransactionStatus status) { 
     updateOperation1(); 
     return resultOfUpdateOperation2(); 
     } 
    }); 
    } 
} 

有關詳細信息,請參閱reference

+0

謝謝,它的工作原理! – smallufo 2010-07-01 07:23:38

相關問題