目前我正在尝试应用程序管理的持久化上下文,通过手动创建实体管理器并将它们存储起来以启用跨越JSE应用程序中的多个请求调用(可能类似于扩展持久性上下文)的事务 .
但是,我想知道我是否可以通过使用spring的@PersistenceContext注入来避免在整个服务和DAO方法中发送entityManager对象作为附加参数,并使用@Transactional注释标记方法以使用与该实体管理器手动启动的事务 .
我想我可以通过使用ThreadLocal来管理这个功能,但我会更高兴能够将它附加到spring框架 .
这是我想到的一个例子:
UI动作方法:
在这里我们可以看到事务是由ui逻辑启动的,因为后端没有外观/命令方法将这些调用分组到业务逻辑:
Long transactionid = tool.beginTransaction();
// calling business methods
tool.callBusinessLogic("purchase", "receiveGoods",
paramObject1, transactionid);
tool.callBusinessLogic("inventory", "updateInventory",
paramObject2, transactionid);
tool.commitTransaction(transactionid);
在工具里面:
public Long beginTransaction() {
// create the entity --> for the @PersistentContext
Entitymanager entityManager = createEntityManagerFromFactory();
long id = System.currentTimeMillis();
entityManagerMap.put(id, entitymanager);
// start the transaction --> for the @Transactional ?
entityManager.getTransaction().begin();
return id;
}
public void commitTransaction(Long transactionId) {
EntityManager entityManager = entityManagerMap.get(transactionId);
entityManager.getTransaction().commit();
}
public Object callBusinessLogic(String module, String function,
Object paramObject, Long transactionid) {
EntityManager em = entityManagerMap.get(transactionId);
// =================================
// HOW TO DO THIS????
// =================================
putEntityManagerIntoCurrentPersistenceContext(em);
return executeBusinessLogic(module, function, paramObject, transactionid);
}
以及服务方法的示例:
public class Inventory {
// How can i get the entityManager that's been created by the tool for this thread ?
@PersistenceContext
private EntityManager entityManager;
// How can i use the transaction with that transactionId ?
@Transactional
public void receiveGoods(Param param) {
// ........
}
}
反正有没有实现这个目标?
谢谢 !
3 回答
Spring对
@PersistenceContext
注释的处理几乎完全是你必须担心线程安全的问题 . 但是你永远不会以这种方式获得扩展的上下文!相信我, Spring 天3和延长的持久性背景,恐怕不是他们关注的焦点 . 如果你想使用扩展的持久化上下文,让Spring注入EntityManagerFactory(通过
@PersistenceUnit
注释),然后自己创建EntityManager . 对于传播,您必须将实例作为参数传递或自己将其存储在ThreadLocal中 .确实有一个应用程序管理的持久化上下文,你需要以某种方式 @Transactional @Transactional & @PersistenceContext 基础设施,为它们提供你的 own 实体管理器,不要让Spring创建它自己的 .
实现这一点的关键是在 TransactionSynchronizationManager 类中稍微注册一下,将自己的实体管理器注册到本地线程,Spring将使用它注入 @PersistenceContext 属性 .
前段时间我对自己的应用程序有这种需求,我设计了一个基于Spring AOP的小型架构来管理扩展的持久化上下文 .
详情:JPA/Hibernate Global Conversation with Spring AOP
当您通过@Transactional配置事务时,您应该将事务的配置切换到注释 .
在这里,您开始交易,然后希望@Transactional也将被触发 .
有关更多信息,您最好开始阅读http://static.springsource.org/spring/docs/2.5.x/reference/transaction.html => 9.5.6 . 使用@Transactional