次のようなステートレス Bean があります。
@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(...) を呼び出します。process(...) の期間は比較的短いですが、processObjects(...) はすべてを実行するのに非常に長い時間がかかる可能性があります。したがって、オープントランザクションを維持したくありません。独自のトランザクション内で動作するには、個々のプロセス (...) 操作が必要です。これは、呼び出しごとに新しいトランザクションである必要があります。最後に、クライアントが process(...) を直接呼び出すためのオプションを開いたままにしておきたいと思います。
私はさまざまな種類のトランザクションを試しました: 決して、サポートされていない、サポートされている (processObjects 上で)、必須、新しい (プロセス上で) が必要ですが、merge() が呼び出されるたびに TransactionRequiredException が発生します。
メソッドを2つの異なるBeanに分割することで、機能させることができました。
@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();
}
}
しかし、これを1つのクラスで達成できるかどうかはまだ興味があります. トランザクション マネージャーは、個々のメソッドにより具体的な注釈が与えられている場合でも、Bean レベルでのみ動作するように見えます。したがって、トランザクションが同じインスタンス内で他のメソッドの呼び出しを開始しないように 1 つのメソッドをマークすると、どのようにマークされていても、トランザクションは作成されませんか?
JBoss Application Server 4.2.1.GA を使用していますが、具体的ではない回答を歓迎/優先します。