@Transactional on方法,但始终出现错误“必须在事务上下文中调用”

时间:2020-03-10 15:01:44

标签: transactions annotations

我正在处理JavaEE批处理,以控制一些数据。 Batchlet进程初始化,然后调用功能方法(用于控制循环),每控制1000行,我就在数据库(JPA)中写入一些信息,以便记录可能的增量。

如果我在一开始将@Transactional批注放在处理方法上,它将起作用,我会在db中找到增量日志。 但是,当控件花费的时间超过事务处理时间时,它就会回滚。

因此(在这里似乎有很多主题建议),我在持久性管理器中将@Transactional放在最接近的增量日志记录方法中。它将日志bean(带有增量信息)转换为一个实体,然后将其合并(javax.persistence.EntityManager.merge),以便在数据库中创建它。

但是,尽管该方法上有@Transactional,但我有错误:

The method public abstract java.lang.Object javax.persistence.EntityManager.merge(java.lang.Object) must be called in the context of a transaction.

有人对我想念的东西有所了解吗?

某些代码:

// package, imports...
@Named("MyBatchlet")
@Dependent
public class MyBatchlet implements Batchlet {
    @Inject
    private Logger logger;
    @Inject
    private MyTF MyTF;
    @Override
//  @Transactional(Transactional.TxType.REQUIRED)
    public String process() {
        // init parameters
        ...

        // Loop on some blocks of data
        try {
            for (String data : datas) {
                status = MyTF.analyzeData();
            }
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @Override
    public void stop() throws Exception {
    }
}

public class MyTF {
    @Inject
    private Logger logger;
    @Inject
    private ManagerPersistance managerPersistance;

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public StatutExecution analyzeData() throws SQLException {
        // init report
        saveReport(synthesis, null);

        // control loop, for ex 100.000 rows
        while (...) {
            ...
            if (position % 1000 == 0) {
                saveReport(synthesis, details);
            }
        }
    }

    @Transactional(Transactional.TxType.REQUIRED)
    public void saveReport(MySynthesis synthesis, List<MyDetail> details) {
        if (synthesis!=null) managerPersistance.saveSynthesis(new MySynthesisEntity (synthesis));
        if (details!=null) {
            for (MyDetail detail : details) {
                managerPersistance.saveDetail(new MyDetailEntity (detail));
            }
        }
    }

    // ...
}

public class ManagerPersistance {
    @Inject
    private Logger logger;
    @Inject
    @MyDatabase
    EntityManager entityManager;

    public void saveSynthesis(MySynthesisEntity synthesis) {
        entityManager.merge(synthesis);
        entityManager.flush();
    }

    public void saveDetail(MyDetailEntity detail) {
        entityManager.merge(detail);
        entityManager.flush();
    }
}

0 个答案:

没有答案