5

注:原因の特定に私が認めたいよりもはるかに多くの時間を費やした後、この質問を短い形式で回答とともに追加します。うまくいけば、私は他の誰かの痛みを救うでしょう。

EJBで注釈が付けられたメソッド呼び出しを委任すると@Singleton、コンテナは次の行に沿って例外をスローします。

TransactionRolledbackLocalException Client's transaction aborted 

シングルトンBeanにはデータアクセスが発生していません。

ServiceBeanImpl.java

@Stateless
@Local
public class ServiceBean extends BaseBean{ 
  @EJB private CacheService cacheService;

  public FooObj getFooFromCache(int id) {
    FooObj fooObj = (FooObj) cacheService.get(id);
    if (fooObj == null) {
      fooObj = getEntityById(FooObj.class, id);
      cacheService.put(id, fooObj);  //This throws exception
    }
    return cacheService.get(id);
  }
}

CacheServiceImpl.java

@Singleton
@Startup
public class CacheServiceImpl implements CacheService {
    private Cache cache;

    @PostConstruct
    public void init() {
        CacheManager instance = CacheManager.getInstance();
        cache = instance.getCache("cache");
    }

    @PreDestroy
    public void destroy() {
        CacheManager.getInstance().shutdown();
    }

    public Object get(Object id) {
      return cache.get(id);
    }

    public void put(Object id, Object obj) {
      return cache.put(id, obj);
    }
}

質問 データアクセスを行わないシングルトンBeanを呼び出すと、トランザクション例外がスローされるのはなぜですか?

4

3 に答える 3

7

簡単な答え: トラップされて伝播されない(したがって、StackTraceに手がかりがない)例外がないか(StackTraceに手がかりがないと仮定して)以前に実行されたコードスタックを確認します。

この特定のケースではtry/catch、名前付きクエリを作成することについての周りがありました。その名前付きクエリが失敗した場合、catchブロックで2次クエリが実行されました。クエリはトランザクションを必要としなかったため、フォールバッククエリは適切に実行され、期待されるエンティティを返しました。

でも...

それはまた(私が思うに)トランザクションをロールバックが必要であるとマークします。豆は@Singletonやや赤ニシンです。そのBeanに制御を移すことについての何かにより、コンテナはトランザクションをチェックし、その時点で例外がスローされましたが、トランザクションが無効になったため、例外は適切でした。

この話の教訓:

  • それがおそらくあなたの問題がある場所であるため、最後のデータベースの相互作用に逆戻りして作業します。
  • 最後のデータベースインタラクションがデータを返したからといって、問題がなかったわけではありません(これは私にとってキラーでした)。
于 2012-10-18T06:06:31.077 に答える