sma*_*ufo 11 spring dao wicket jpa transactions
我有一个wicket页面,其中包含两个Spring管理的bean,一个是DAO,另一个是Service Object:
public class MergeAccountsPage extends WebPage
{
@SpringBean
private MergeEmailDao mergeEmailDao;
@SpringBean
private MergingService mergingService;
}
Run Code Online (Sandbox Code Playgroud)
该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(...);
}
};
Run Code Online (Sandbox Code Playgroud)
该链接将调用mergeAccoungDao.update(ma)以更新DB中的行.
但该数据未更新为DB,我认为这是因为DAO不裹@Transaction也不tx:advice和aop标签.
我想知道有没有办法以编程方式获取事务管理器,并手动打开/关闭事务?
注意:我可以通过在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>
Run Code Online (Sandbox Code Playgroud)
这样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
Run Code Online (Sandbox Code Playgroud)
因此,如果此事务管理器应用程序"推荐"此AbstractDAO的CRUD,则其他DAO可能会出现问题,因为其他DAO可能依赖于txManagerForum,txManagerBank,txManagerUser等.
回到问题,有没有办法以编程方式获取txManager?如 :
TransactionManager txManager = TxManagerThreadLocal.get();
txManager.begin();
ma.setNewEmailSentTime(null);
mergeAccoungDao.update(ma);
txManager.commit();
Run Code Online (Sandbox Code Playgroud)
或者有没有更好的方法将事务包装到DAO?
非常感谢.
Abh*_*kar 15
您必须在要使用它的类中注入事务管理器.您可以为其使用构造函数或基于属性的注入,或使用自动装配.如果你得到了事务管理器,你可以使用Spring中的程序化事务支持来启动和提交事务.以下是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();
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅参考.
| 归档时间: |
|
| 查看次数: |
25604 次 |
| 最近记录: |