JTA EntityManager не может использовать getTransaction () в вызове хранимой процедуры

Я хочу выполнить асинхронное транзакционное действие в методе ejb, вызвав хранимую процедуру. Когда я вызываю метод, я даю ошибку ниже:

java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()

фасоль

@Stateless
public class FileSearchDAO {
    private static Logger logger = LoggerFactory.getLogger(FileSearchDAO.class);

    @PersistenceContext(unitName = "FileSearchPU")
    private EntityManager entityManager;

    @Asynchronous
    public Future<String> saveFile(String fileNo, List<String> runningFiles) {
        try {
            entityManager.getTransaction().begin();
            entityManager.createNativeQuery(
                    " BEGIN prc_save_file (:fileNo); END;")
                    .setParameter("fileNo", fileNo).executeUpdate();
            entityManager.getTransaction().commit();
            runningFiles.remove(fileNo);
            return new AsyncResult<>(fileNo);
        } catch (Exception ex) {
            ex.printStackTrace();
            return new AsyncResult<>(ex.getMessage());
        }
    }

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <persistence-unit name="FileSearchPU" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>jdbc/FileSearchDS</jta-data-source>
        <properties>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.transaction.jta.platform"
                      value="${hibernate.transaction.jta.platform}"/>
        </properties>
    </persistence-unit>
</persistence>

У меня нет класса Entity. Я просто хочу вызвать хранимую процедуру, которая обновляет некоторую таблицу.


person mohammad_1m2    schedule 17.12.2017    source источник


Ответы (1)


В JTA управляемом контейнере источника данных транзакции обрабатываются распределенным образом, поэтому параллелизм также обрабатывается, например, вне вашего приложения.

EntityManagers транзакция не может использоваться, потому что это локальная транзакция, поэтому то, что затем не обрабатывается за пределами вашего приложения. Прочтите также этот пост для получения дополнительной информации.

Если вам нужна транзакция, вы должны использовать UserTransaction

@Resource
UserTransaction utx;

Чтобы использовать его, аннотируйте свой bean-компонент

@TransactionManagement(TransactionManagementType.BEAN)

и используйте транзакцию, например

utx.begin();
   ...
utx.commit(); // utx.rollback();
person pirho    schedule 17.12.2017
comment
Спасибо. Также необходим em.joinTransaction ()? - person mohammad_1m2; 17.12.2017
comment
@ mohammad_1m2 Я думаю, что в этом нет необходимости или это не имеет значения в вашем случае, поскольку контекст сохранения может в любом случае не знать, что происходит в вашей хранимой процедуре. Но в случае, если вы работали с сущностями, да. Тем не менее предполагаю, что это не повредит, если использовать. - person pirho; 17.12.2017