spring - 如何使用 JAX-RS、Spring 和 JPA 管理事务

标签 spring jpa transactions jax-rs

我正在使用 JAX-RS 提供基于 HTTP 的接口(interface)来管理数据模型。数据模型存储在数据库中并通过 JPA 进行交互。

这使我可以修改数据模型的接口(interface)以适应 REST 客户端,并且大多数情况下似乎工作得很好。但是,我不确定如何处理 JAX-RS 资源提供的方法需要事务的场景,这会影响 JPA 的 get、update、commit-on-tx-end 模式,因为只有一个事务包装get 操作,因此永远不会提交更新。如果单个 REST 操作需要多个 JPA 操作,我会看到同样的问题。

当我使用 Spring 的事务支持时,显而易见的事情是应用 @Transactional JAX-RS 资源中的这些方法。但是,为了使其工作,Spring 需要管理 JAX-RS 资源的生命周期,并且我知道的使用示例在需要时通过“new”创建资源,这让我有点紧张。

我可以想到以下解决方案:

  • 更新我的 JPA 方法,以原子方式从我的 REST 接口(interface)提供我想要执行的所有操作的事务管理版本。应该可以工作,将事务排除在 JAX-RS 层之外,但会阻止 get、update、commit-on-tx-end 模式,这意味着我需要创建一个非常精细的 JPA 接口(interface)。
  • 注入(inject)资源对象;但它们通常是有状态的,至少持有与
  • 交互的对象的 ID。
  • 抛弃资源层次结构,在根目录注入(inject)大量无状态的 super 资源,从该根目录管理整个层次结构;没有凝聚力,大服务
  • 具有注入(inject)的、无状态的、支持事务的辅助对象的层次结构,这些对象“隐藏”实际资源;资源被实例化并保持状态,但将方法调用委托(delegate)给辅助对象

  • 有人有什么建议吗?我很可能在某个地方错过了一些关键点。

    更新 - 为了解决围绕 get、update、commit-on-tx-close 流程缺少事务的问题,我可以公开 EntityManager merge(object) 方法并手动调用它。不整洁,但不能解决更大的问题。

    更新 2 @skaffman
    代码示例:
    在 JPA 服务层,注入(inject),注释工作
    public class MyEntityJPAService {
    ...
    @Transactional(readOnly=true) // do in transaction
    public MyEntity getMyEntity(final String id) {
        return em.find(MyEntity.class, id);
    }
    

    在 JAX-RS 资源中,由新创建的,没有事务
    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...
    }
    

    最佳答案

    我有几个建议

  • 在 JPA 和 JAX-RS 层之间引入一个层。该层将由 Spring 管理的 @Transactional 组成。 bean,并将通过其组件 JPA 调用组成各种业务级操作。这有点类似于您的 (1),但保持 JPA 层简单。
  • 用提供相同(或相似)功能的 Spring-MVC 替换 JAX-RS,包括 @PathVariable , @ResponseBody
  • 使用 TransactionProxyFactorybean 以编程方式将您的 JAX-RS 对象包装在事务代理中.这会检测到您的 @Transactional注释并生成尊重它们的代理。
  • 使用@Configurable和 AspectJ LTW 允许 Spring 兑现 @Transactional即使您使用 `new.见 8.8.1 Using AspectJ to dependency inject domain objects with Spring
  • 关于spring - 如何使用 JAX-RS、Spring 和 JPA 管理事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9601843/

    相关文章:

    java - BlazeDS 二进制最新版本下载位置

    Mercurial abort : Input/output error, 交易中止!回滚完成

    java - 在 Java JMS Spring 中为方法参数声明 Final

    java - Spring Data JPA save() 方法不遵循 hashcode/equals 约定

    java - JPA 中的参数化查询出现 "org.hibernate.QueryException: Unable to resolve path..."错误

    java - 如何阻止WebSphere自动创建EntitMangerFactory?

    c# - C# 中的对象事务

    java - 使用@JsonCreator 和@JsonProperty 未按预期生成 Json 响应

    java - Spring 数据 : How to lock a row in a transaction and make other transactions wait until it is released?

    spring - Spring Kafka 和 Spring Integration Kafka 的区别