如何使用JAX-RS、Spring和JPA管理事务
我正在使用JAX-RS提供一个基于HTTP的接口来管理数据模型。数据模型存储在数据库中,并通过JPA与之交互 这使我能够修改数据模型的接口以适应REST客户机,而且大多数情况下似乎工作得很好。但是,我不确定如何处理JAX-RS资源提供的方法需要事务的场景,这会影响JPA get、update、commit on tx end模式,因为只有一个事务包装get操作,所以永远不会提交更新。如果单个REST操作需要多个JPA操作,我可以看到同样的问题 当我使用Spring的事务支持时,显然要做的事情是将如何使用JAX-RS、Spring和JPA管理事务,spring,jpa,transactions,jax-rs,Spring,Jpa,Transactions,Jax Rs,我正在使用JAX-RS提供一个基于HTTP的接口来管理数据模型。数据模型存储在数据库中,并通过JPA与之交互 这使我能够修改数据模型的接口以适应REST客户机,而且大多数情况下似乎工作得很好。但是,我不确定如何处理JAX-RS资源提供的方法需要事务的场景,这会影响JPA get、update、commit on tx end模式,因为只有一个事务包装get操作,所以永远不会提交更新。如果单个REST操作需要多个JPA操作,我可以看到同样的问题 当我使用Spring的事务支持时,显然要做的事情是将
@Transactional
应用于JAX-RS资源中的这些方法。然而,为了让这项工作正常进行,Spring需要管理JAX-RS资源的生命周期,我所知道的使用示例在需要时通过“new”创建资源,这让我有点紧张
我可以想出以下解决办法:
更新-为了解决在get、Update、commit on tx close流中缺少事务的问题,我可以公开EntityManager合并(object)方法并手动调用它。不整洁,但不能解决更大的问题
更新2@skaffman 代码示例: 在JPA服务层中,注入的注释起作用
public class MyEntityJPAService {
...
@Transactional(readOnly=true) // do in transaction
public MyEntity getMyEntity(final String id) {
return em.find(MyEntity.class, id);
}
在JAX-RS资源中,由new创建,没有事务
public class MyEntityResource {
...
private MyEntityJPAService jpa;
...
@Transactional // not injected so not effective
public void updateMyEntity(final String id, final MyEntityRepresentation rep) {
MyEntity entity = jpa.getMyEntity(id);
MyEntity.setSomeField(rep.getSomeField());
// no transaction commit, change not saved...
}
我有一些建议
@Transactional
bean组成,并将从组件JPA调用组成各种业务级别的操作。这有点类似于(1),但保持了JPA层的简单性@PathVariable
,@ResponseBody
等TransactionProxyFactorybean
以编程方式将JAX-RS对象包装到事务代理中。这将检测您的@Transactional
注释,并生成一个代理来尊重它们@Configurable
和AspectJ LTW允许Spring尊重@Transactional
,即使您使用“new”创建对象也是如此。看这些建议是否按优先顺序排列(根据您)?