1

是否可以在 CMT(容器管理事务)无状态 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 类创建函数中的函数上方,CMT 在第一个事务中创建了第二个事务。当从第二个事务中抛出异常时,我的 BookResource 类创建方法可以捕获它。不需要BMT。

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

我注意到注释仅在放置在单个方法上时才有效,将其放置在类本身不会产生影响。

于 2013-08-15T12:45:47.097 回答