关于 java:Spring EntityManager Commit Transaction as 方法完成

Spring EntityManager Commit Transaction as method completes

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

1
2
3
4
5
6
7
    @Override
    @Transactional
    public void upsert(String lastSuccessfullRun) {
        for( tableData in Tables){
         insertIntoDB(tableData);
       }
    }

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

1
2
3
4
5
    @Override
    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void insertIntoDB (String tableData) {
        em.persist(tableData)
    }

但问题是该方法没有提交,因为它返回到 upsert 方法中的下一个循环。

我如何提交方法完成?


检查文档。

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.

即使你的方法是公共的,你在同一个类的另一个方法中调用它,所以你不会通过代理和 insertIntoDB 方法上的 @Transactional(propagation=Propagation.REQUIRES_NEW) 没有效果。

所以在 AspectJ 模式下尝试一下,就像在文档中一样。


尝试使用如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@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 代理时才有效,因此在您的情况下它不起作用。如果您真的希望您的更改反映在数据库和与您的活动事务关联的 PersistenceContext 中,您可以使用

1
EntityManager.flush();

但是请记住,在使用flush()时,数据的更改在遇到flush后会反映在数据库中,但它仍在事务中,可以回滚并且事务仍然处于活动状态,但是当您使用commit()时对数据库进行了更改