Распространение транзакции EJB3

У меня есть бин без гражданства что-то вроде:

@Stateless
public class MyStatelessBean implements MyStatelessLocal, MyStatelessRemote {
    @PersistenceContext(unitName="myPC")
    private EntityManager mgr;

    @TransationAttribute(TransactionAttributeType.SUPPORTED)
    public void processObjects(List<Object> objs) {
        // this method just processes the data; no need for a transaction
        for(Object obj : objs) {
            this.process(obj);
        }
    }

    @TransationAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void process(Object obj) {
        // do some work with obj that must be in the scope of a transaction

        this.mgr.merge(obj);
        // ...
        this.mgr.merge(obj);
        // ...
        this.mgr.flush();
    }
}

Тогда обычно используется то, что клиент будет вызывать processObjects (...), который фактически не взаимодействует с менеджером сущностей. Он делает то, что ему нужно, и вызывает process (...) индивидуально для каждого объекта для обработки. Длительность процесса (...) относительно короткая, но для выполнения processObjects (...) может потребоваться очень много времени. Поэтому я не хочу, чтобы он поддерживал открытую транзакцию. яdo необходимо, чтобы отдельные процессы (...) выполнялись в рамках собственной транзакции. Это должна быть новая транзакция для каждого звонка. Наконец, я бы хотел оставить опцию открытой, чтобы клиент мог напрямую вызывать процесс (...).

Я пробовал несколько разных типов транзакций: никогда, не поддерживается, поддерживается (для processObjects) и требуется, требует new (on process), но я получаю TransactionRequiredException каждый раз, когда вызывается merge ().

Я смог заставить его работать, разделив методы на две разные компоненты:

@Stateless
@TransationAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class MyStatelessBean1 implements MyStatelessLocal1, MyStatelessRemote1 {
    @EJB
    private MyStatelessBean2 myBean2;

    public void processObjects(List<Object> objs) {
        // this method just processes the data; no need for a transaction
        for(Object obj : objs) {
            this.myBean2.process(obj);
        }
    }
}

@Stateless
public class MyStatelessBean2 implements MyStatelessLocal2, MyStatelessRemote2 {
    @PersistenceContext(unitName="myPC")
    private EntityManager mgr;

    @TransationAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void process(Object obj) {
        // do some work with obj that must be in the scope of a transaction

        this.mgr.merge(obj);
        // ...
        this.mgr.merge(obj);
        // ...
        this.mgr.flush();
    }
}

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

Я использую JBoss Application Server 4.2.1.GA, но неспецифичные ответы приветствуются / предпочтительны.

Ответы на вопрос(8)

Ваш ответ на вопрос