【问题标题】:handling JPA transactions exceptions处理 JPA 事务异常
【发布时间】:2013-04-15 19:24:02
【问题描述】:

我有 3 个 EJB:

第一个是为了持久化:

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class PersistenceService
{
    @PersistenceContext(unitName="pc")
    EntityManager em;

    public <T> void create(T entity) {
        em.persist(entity);
    }
}

第二个是商务:

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class BusinessService implements 
{
    @EJB
    PersistenceService persistenceService;

    public <T> void register (User user) {
            try{
                    // Do some business
                    persistenceService.persist(user);
                    // Do other business
            }catch(Exception e){
                    // log exception
                    throw new BusinessException(e);
            }
      }
}

第三个是调用业务EJB的Web服务。

问题是业务EJB没有捕获数据库异常,例如由封装在EJB异常中的Mysql连接器抛出的约束冲突异常。我可以在 Rest 服务 EJB 中处理此异常,但不能在业务 EJB 中处理。我认为这与交易有关。

我不确定应该将哪些事务属性添加到 Persistence EJB 和业务 EJB 以让我在业务 EJB 中捕获这些类型的异常。

【问题讨论】:

  • 为什么不能在业务层处理异常?你发现有什么例外吗?
  • 因为异常发生在业务方法范围之外的事务中。

标签: jakarta-ee jpa exception-handling transactions


【解决方案1】:

您是对的,显示的行为可能与事务边界有关。您的 Web 服务(我现在猜)是上层的非 EJB 层,因此当您调用 BusinessService.register() 时,事务在调用之前开始,在调用返回之前结束。

运行时异常发生在提交时,在您的情况下发生在 register() 方法的代码结束之后;因此,现在处理它们还为时过早。

如果您真的不想处理 Web 服务 bean 中的异常,您有两个选择:

一。BusinessService bean 中使用bean 管理的事务

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class BusinessService 
{
@EJB
PersistenceService persistenceService;
@Resource
private UserTransaction ut;

public <T> void register (User user) {
        try{
                ut.begin();
                // Do some business
                persistenceService.persist(user);
                // Do other business
                ut.commit();
        }catch(Exception e){
                // log exception
                throw new BusinessException(e);
        }
  }
}

两个。在 Web 服务 bean 和 EJB 之间引入一个非事务性外观:

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public FacadeBean {

    @EJB private BusinessService businessService;

    public void facadeMethod(User user) {
        try {
            businessService.register(user);
        } 
        // your handling code here
        catch (...) { ... }
    }

}

【讨论】:

  • 感谢分享:),认为非事务层更好,因为我仍然喜欢容器管理的事务。
猜你喜欢
  • 2015-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-03
  • 2020-05-27
  • 2015-06-18
  • 2013-07-10
相关资源
最近更新 更多