Spring EntityManager 在方法完成时提交事务

Spring EntityManager Commit Transaction as method completes

我正在使用 spring EntityManager 并且需要在方法完成时提交记录。那就是我有两种方法用于 ex ::

    @Override
    @Transactional
    public void upsert(String lastSuccessfullRun) {
        for( tableData in Tables){
         insertIntoDB(tableData);
       }
    }

并且方法 insertIntoDB 包含实际执行更新查询的业务逻辑

    @Override
    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void insertIntoDB (String tableData) {
        em.persist(tableData)
    }

但问题是方法 没有提交 因为它 returns 用于 upsert 方法中的下一个循环。

我如何提交方法完成?

检查documentation

Method visibility and @Transactional

When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.

即使您的方法是 public,您也在同一 class 中的另一个方法中调用它,因此您不会通过代理和 @Transactional(propagation=Propagation.REQUIRES_NEW) insertIntoDB 方法无效。

所以在 AspectJ 模式下尝试,如文档中所述。

尝试使用如下所示:

@Override
    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void upsert(String lastSuccessfullRun) {
        for( tableData in Tables){
         insertIntoDB(tableData);
       }
    }



@Override
    @Transactional(propagation=Propagation.SUPPORTS)
    public void insertIntoDB (String tableData) {
        em.persist(tableData)
    }

如果您在 insertIntoDB 方法中使用 "propagation=Propagation.REQUIRES_NEW" 那么它将创建一个新事务并在 insertIntoDB 方法完成时提交它。

@Transactional 仅在您调用方法 throw proxy 时有效,因此在您的情况下它不起作用。如果您真的希望您的更改反映在数据库和与您的活动事务关联的 PersistenceContext 中,您可以使用

EntityManager.flush();

但是要记住,使用flush()时,数据的变化在遇到flush后会反映到数据库中,但它仍然在事务中,可以回滚,事务仍然处于活动状态,但是当你使用commit( ) 对数据库进行了更改,事务也到此结束。