Методы транзакций Java EE, помеченные как не поддерживаемые - PullRequest
0 голосов
/ 21 июля 2011

У меня есть метод, который передает данные из одной базы данных в другую и в процессе создает новые таблицы в целевой базе данных. Метод является частью EJB без сохранения состояния (Java EE 6, GF 3.1), поэтому контейнер по умолчанию запускает распределенную транзакцию при вызове метода.

Процесс передачи данных по существу выполняется в виде двух отдельных шагов: 1. чтение из исходной базы данных 2. запись в целевую базу данных. Если этап чтения завершается неудачно, я не хочу, чтобы этап записи выполнялся, но если этап записи завершается неудачно и чтение уже завершено, мне все равно - я просто выброшу данные.

Изначально я столкнулся с проблемой, что мои источники данных не были XADataSource, поэтому контейнер пожаловался на это. Затем я преобразовал их в XADataSource, но все равно не получилось, потому что процесс записи (который находится в базе данных MySQL) содержит операторы create table, которые вызывают неявное принятие, и вы не можете сделать это в распределенной транзакции.

Решение, к которому я наконец пришел, состоит в том, чтобы пометить метод передачи как TransactionAttributeType.NOT_SUPPORTED, а затем поместить процесс чтения и записи в их собственные методы, которые вызываются родительским методом передачи.

Мой вопрос, однако, заключается в следующем: методы чтения и записи выполняются внутри своих собственных транзакций или NOT_SUPPORTED распространяется на них? Я предполагаю, что они имеют неявный TransactionAttributeType.REQUIRED и поэтому начнут свою собственную транзакцию, но я не уверен, и я думаю, что важно, чтобы они выполнялись внутри транзакции.

Это лучшее решение этой проблемы?

1 Ответ

1 голос
/ 22 июля 2011

Больший вопрос для разделения шагов чтения и записи состоит в том, должен ли шаг записи все еще выполняться, если какой-то другой поток / процесс изменяет данные, полученные из шага чтения. Другими словами, вы уверены, что чтение и запись не должны быть в одной транзакции? Возможно, у вас есть какая-то внешняя гарантия, что не будет проблем с записью данных отдельно.

Как называются методы чтения и записи? Если они вызываются как локальные методы, то NOT_SUPPORTED будет распространяться. Если они вызываются через прокси-объект сессионного компонента, то по умолчанию применяется REQUIRED:

@Stateless
@Local(MyIntf.class)
public class MyBean {
    @EJB
    private MyIntf ivMyBean; // Self-injection

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public void method() {
        // Use the injected proxy rather than "this.read()" to ensure that the
        // default REQUIRED transaction attribute is used for the DB operations.
        MyResults results = ivMyBean.read();
        ivMyBean.write(results);
    }

    public MyResults read() { ... }
    public void write(MyResults results) { ... }
}

Кажется несколько сомнительным, что вам нужно создавать таблицы на основе прочитанных данных. Неужели нет способа сделать это как отдельную операцию? Я бы предложил внешний метод REQUIRED, который выполняет операцию чтения, затем вызывает метод NOT_SUPPORTED для создания таблиц и, наконец, выполняет операцию записи в той же транзакции, что и чтение, которая была временно приостановлена ​​во время работы метода NOT_SUPPORTED.

...