1

グラスフィッシュにデプロイされたwarファイルがあります。Singleton Bean があり、その中に 1 つの同期メソッドがあります。

@TransactionAttribute (TransactionAttributeType.REQUIRED)
public synchronized void do()
{
    ...
}

ただし、メソッドが呼び出される前にトランザクションが開始されることに気付きました。呼び出し元が Bean クラスのモニターでロックを取得した後、トランザクションを開始するにはどうすればよいですか?

ありがとうございました。

更新: 一度に 1 つのスレッドからしか呼び出せない Bean メソッドを作成しようとしています。前のスレッドが完全に処理を完了するまで、他のスレッドがこのメソッドを呼び出さないようにします。シングルトン Bean を使用するというアイデアを得た別のスレッドを作成しました:グラスフィッシュで期待どおりに動作しないステートレス セッション Bean の同期メソッド

更新: いくつか読んだ後、自分のトランザクション UserTransaction を作成できるようです。それはサポートされますか?どうでも。次のエラー メッセージが表示されました。

Only session beans with bean-managed transactions can obtain UserTransaction
4

2 に答える 2

1

1 つの方法は、別の Bean 内のメソッドへの呼び出しをラップすることによって、Bean から同期を移動することだと思います (YourBean は、Bean クラスのインターフェースになります)。

public class WrapperBeanImpl implements WrapperBean {

  private YourBean yb;

  private final Object lock;

  @Resource
  private SessionContext ctx;

  @PostConstruct
  public void init() {
    yb = ctx.getBusinessObject(YourBean.class);
  }

  @TransactionAttribute(TransactionAttributeType.NEVER)
  public void synchronizedDo() {
    synchronized(lock) {
      yb.do();
    }
  } 
}

( http://www.javahelp.info/2009/11/01/using-transactionattribute-in-submethods-on-same-ejb3-beans/からわずかに変更された例)

もちろん、これは問題にはならないかもしれませんが、この余分な同期をバイパスして do() メソッドを直接呼び出すことを実際に止めるわけではありません。追加の保護手段として、同期を Bean に残すオプションもあります。

于 2014-08-19T05:11:03.577 に答える
0

@ConcurrencyManagementType(CONTAINER)クラス レベルで使用するだけで、コンテナーは同期を維持します。そして、指示なしでメソッドを使用してくださいsynchronized

于 2014-08-25T06:59:13.203 に答える