Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jakarta ee 如何制作弹性EJB';可能引发系统异常(如PSQLException)的_Jakarta Ee_Exception Handling_Ejb_Rollback_Glassfish 4.1 - Fatal编程技术网

Jakarta ee 如何制作弹性EJB';可能引发系统异常(如PSQLException)的

Jakarta ee 如何制作弹性EJB';可能引发系统异常(如PSQLException)的,jakarta-ee,exception-handling,ejb,rollback,glassfish-4.1,Jakarta Ee,Exception Handling,Ejb,Rollback,Glassfish 4.1,我有一个运行在GlassFish 4.1中的EJB,它可能会偶尔抛出系统异常,比如PSQLException。在一种特定情况下,当尝试使用现有唯一键值将记录写入db时,会引发重复键异常。我尝试捕获所有异常,并将org.postgresql.util.PSQLException(和其他)作为异常类添加到applicationexception中的ejb-jar.xml中,但调用总是回滚事务。我希望我的EJB能够适应这些类型的异常。如果我能够捕获异常甚至忽略它们,我的应用程序就可以从这些问题中恢复。

我有一个运行在GlassFish 4.1中的EJB,它可能会偶尔抛出系统异常,比如PSQLException。在一种特定情况下,当尝试使用现有唯一键值将记录写入db时,会引发重复键异常。我尝试捕获所有异常,并将org.postgresql.util.PSQLException(和其他)作为异常类添加到applicationexception中的ejb-jar.xml中,但调用总是回滚事务。我希望我的EJB能够适应这些类型的异常。如果我能够捕获异常甚至忽略它们,我的应用程序就可以从这些问题中恢复。我怎样才能做到这一点

这里有一个例子。我有一个Servlet,当我用web浏览器点击它时,它会调用这个EJB方法:

public void initialize() {  
    try {  
        User user = new User(0, "John", "Doe");  
        em.persist(user);  
        em.flush();  
    } catch(Exception e) {  
        e.printStackTrace();  
    }
我的ejb-jar.xml包含以下内容:

<application-exception>
   <exception-class>org.postgresql.util.PSQLException</exception-class>
    <rollback>false</rollback>
    <inherited>true</inherited>
</application-exception>

org.postgresql.util.PSQLException
假的
真的
对我有效的解决方案是由高风险公司提供的。“解决方案是简单地将‘initialize’标记为非事务性,并将其放入一个单独的方法中,该方法在每次尝试时启动一个新事务。”

更新:这个解决方案不像我想的那样工作。我的申请中有一个错误,这使它看起来像是可行的。修复错误后,我又回到了同一个问题。PSQLException似乎不可捕获,因为它是一个系统异常。我尝试了容器管理和bean管理的方法。我不同意第二次尝试持久化记录会导致系统异常。在分布式环境中,这是可能发生的。这应该是一种可恢复的情况


更新:我使用下面发布的解决方案解决了我的问题。

这肯定与JPA无关,它与PostgreSQL如何处理事务内部的错误状态有关

在您的情况下,它要么自动回滚到DB级别,要么将事务标记为处于不一致状态。您无法/不应该从业务层内部恢复的内容

解决方案是简单地将“initialize”标记为非事务性,并将这些内容放入一个单独的方法中,该方法为每次尝试启动一个新事务


编辑:我的答案仅适用于您实际设法在catch块中捕获异常的情况,如果您没有,则意味着您只是在提交过程中获取异常,在这种情况下,上述解决方案也适用。

这是我选择的一种适合我的解决方案。而不是注入PersistenceContext:

@PersistenceContext
private EntityManager em;
我正在注入一个数据源资源:

@Resource(lookup = "jdbc/sloocefw")
private DataSource dataSource;
这使我能够创建自己的SQL语句(这一点很重要),使我能够在尝试插入具有重复键的行时捕获SQLException

public void initialize() {  
    try (Connection connection = dataSource.getConnection()) {
        PreparedStatement ps = connection.prepareStatement("INSERT INTO user (id, firstName, lastName) VALUES (" + id + ", 'John', 'Doe')");
        ps.executeUpdate();
    } catch(SQLException e) {
        e.printStackTrace();
    }
}
我现有的用户实体bean管理id(自动递增)。我需要更改为手动管理(如上面的示例中所示)或使用数据库自动增量


我更愿意使用实体bean,但当我使用实体bean尝试插入重复键时,会导致无法捕获的系统异常。

为了捕获
PSQLException
或任何其他与数据库相关的异常,需要手动刷新实体管理器。否则,您的更改将在方法完成后(提交期间)刷新,因此您无法捕获它。若系统异常离开EJB,那个么它将被销毁,事务将回滚。谢谢Geinmachi,但对我来说它并没有任何改变。下面的代码仍然回滚事务
try{User User User=new User(0,“John”,“Doe”);em.persist(User);em.flush();}catch(异常e){e.printStackTrace();}
PSQLException
是系统异常,而不是应用程序异常,因此将其添加到
中没有意义。了解更多关于EJB.Geinmachi的信息,还有其他建议吗?我已经更新了这个问题。非常感谢。这个解决方案是可行的,也是我正在寻找的。@ NHO JoToM,它的答案是有用的,请考虑把它标记为正确的ANWSER。我更新了这个问题。此解决方案不起作用,因为PSQLException看起来像是无法捕获的SystemException。还有其他想法吗?