猿问

如何在Spring事务外执行JPA代码

我想优化只读查询,所以我想在事务之外执行 JPQL 查询,以便从 JPQL 返回的实体不会在当前持久性上下文中进行管理(为了节省脏检查和不必要的管理这些实体的成本,以节省 2 倍的大小)在持久性上下文中)。


我在下面尝试过,


@Repository

public class CustomPostRepository {


  @Autowired

  private EmployeeRepository employeeRepository;



  @Transactional

  public void foo() {

      // Some other transactional code (read-write) here ...


      final TransactionStatus transactionStatus = TransactionAspectSupport.currentTransactionStatus(); // returns current active transaction

      System.out.println("transactionStatus.isNewTransaction() = " + transactionStatus.isNewTransaction()); // returns TRUE


      List<Post> posts = employeeRepository.bar();


     // Some other code here...

  }

}



@Repository

public class CustomJpaEmployeeDao implements EmployeeRepository {


    @PersistenceContext

    private EntityManager em;


    @Override

    @Transactional(propagation = Propagation.NOT_SUPPORTED)

    public List<Post> bar() {

        // Ideally this method should throw Exception, as transaction is expected to be suspended (not exists here)

        final TransactionStatus transactionStatus = TransactionAspectSupport.currentTransactionStatus();


        final List<Post> post = em.createNamedQuery("Post.findAllForReporing", Post.class).getResultList();

        System.out.println("entityManager.contains(post) = " + em.contains(post.get(0))); // returns true, which should be false


        return post;

    }

}

呼叫者,


@Test

public void jpqlTest() {

    customPostRepository.foo();

}

我想EmployeeRepository#bar在事务之外执行(由 C 创建ustomPostRepository#bar),但Propagation.NOT_SUPPORTED不起作用,并且来自 JPQL 的所有选定实体都在当前持久性上下文中进行管理。


那么,有什么方法可以避免管理这些实体或在事务之外执行代码呢?或者这里缺少什么?


qq_遁去的一_1
浏览 128回答 1
1回答

慕村9548890

您应该删除@Transactional注释。在这种情况下,除非方法本身不抛出异常,否则不会产生任何影响LazyInitializationException。如果存在需要事务的情况,则必须为其创建一个单独的方法/从同一个 bean 调用它,这样就不会创建代理。也不EntityManager#contains检查进程是否在事务内运行或实体是否经过脏检查。如果您不想/无法更改这些方法,请使用EntityManager#detach.
随时随地看视频慕课网APP

相关分类

Java
我要回答