1

CMT(Container Managed Transaction) ステートレス Bean で例外をキャッチすることは可能ですか?

以下のコードは、私が試したときに例外をキャッチしません。BMT(Bean Managed Transaction)を使えば例外をキャッチできます。しかし、私はCMTに残りたいです。

@Path("books")
public class BookResource 
{

    @EJB
    private BooksFacade book_facade;

    private Books local_book;


    @POST
    @Consumes({"application/xml", "application/json"})
    public Response create(Books entity) 
    {
       try 
        {
            book_facade.create(entity);
        } catch (RuntimeException ex) 
        {
            System.out.println("Caught database exception");
        }
       return Response.status(Response.Status.CREATED).build();
    }



 public class TXCatcher
{

    //@Resource
    //UserTransaction tx;
    private final static Logger LOG = Logger.getLogger(TXCatcher.class.getName());

    @AroundInvoke
    public Object beginAndCommit(InvocationContext ic) throws Exception 
    {
        //ic.proceed();
        System.out.println("Invoking method: " + ic.getMethod());
        try 
        {
            //tx.begin();
            Object retVal = ic.proceed();
            //tx.commit();
            return retVal;
        }catch (RollbackException e) 
        {
            LOG.log(Level.SEVERE, "-----------------Caught roolback(in interceptor): {0}", e.getCause());
            System.out.println("Invoking method: " + ic.getMethod());
            throw new CustomEx("Database error");
        }catch (RuntimeException e) 
        {
            LOG.log(Level.SEVERE, "-----------------Caught runtime (in interceptor): {0}", e.getCause());
            System.out.println("Invoking method: " + ic.getMethod());
            //tx.rollback();

            throw new CustomEx("Database error",e.getCause());
            //throw new CustomEx("Database error");
        }



        //return ic.proceed();


    }

}

4

2 に答える 2

0

キャッチしようとしている問題の種類によって異なります。明示的な EntiyManager.flush を試すこともできますが、データ ソースの分離レベルによっては、トランザクションがコミットされるまで一部のエラーをキャッチできず、CMT のトランザクション コミット エラーをキャッチするメカニズムがありません。その場合、唯一のオプションは BMT を使用することです (使用したくないと言っていましたが)。これをより使いやすくする唯一の提案は、CMT と同様に動作する EJB インターセプターを作成することです (つまり、インターセプターに UserTransaction を挿入し、 で開始/コミット/ロールバックします@AroundInvoke)。

于 2013-08-14T21:44:11.407 に答える
0

私の BooksFacade クラスの create 関数の関数の上に以下を配置することで、CMT は最初のトランザクション内に 2 番目のトランザクションを作成しました。2 番目のトランザクションから例外がスローされたとき、私の BookResource クラスの create メソッドは例外をキャッチできました。BMTは必要ありません。

@Overide
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void create(Books entity) 
{
    super.create(entity);
}  

注釈は、個々のメソッドに配置した場合にのみ機能し、クラス自体に配置しても違いはありません。

于 2013-08-15T12:45:47.097 に答える