【问题标题】:JTA not rolling back when deleting cascade fails删除级联失败时 JTA 不回滚
【发布时间】:2013-01-03 03:52:56
【问题描述】:

使用:Glassfish 3.1.2、EclipseLink。

我有以下三类JPA模型:

@Entity public class Customer implements Serializable {

@Id private Integer id;

@OneToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, orphanRemoval=true)
private Person person;

[...]

@Entity public class Person implements Serializable {

@Id private Integer id;

[...]

@Entity public class Request implements Serializable {

@Id private Integer id;

@ManyToOne private Person person;

我尝试使用以下策略移除客户(使用 CMT):

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="MyPU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
        <property name="eclipselink.ddl-generation" value="create-tables"/>
        <property name="eclipselink.ddl-generation.output-mode" value="database"/>

        <property name="eclipselink.logging.level" value="FINE"/>
        <property name="eclipselink.logging.parameters" value="true"/>
        <property name="eclipselink.logging.logger" value="DefaultLogger"/>                  
        <property name="eclipselink.logging.timestamp" value="true"/>
        <property name="eclipselink.logging.session" value="false"/>
        <property name="eclipselink.logging.thread" value="false"/>
    </properties>
</persistence-unit>

[...]

@PersistenceContext(unitName="MyPU")
private EntityManager entityManager;   

@Resource private SessionContext context;

[...]

public void delete(Entity object) {

    try{

        object = this.getEntityManager().merge(object);
        this.getEntityManager().remove(object);

    } catch (Exception e){

        this.context.setRollbackOnly();
    }
}

Customer 对象附加到附加到 RequestPerson 对象时,Person 失败导致事务回滚,但 客户 已从数据库中删除。我收到以下错误:

INFO: [EL Fine]: 2012-12-28 10:53:38.1--Connection(27132168)--DELETE FROM CUSTOMER WHERE (ID = ?)
bind => [97]
INFO: [EL Fine]: 2012-12-28 10:53:38.125--Connection(27132168)--DELETE FROM PERSON WHERE (ID = ?)
bind => [111]
INFO: [EL Fine]: 2012-12-28 10:53:38.126--SELECT 1
WARNING: DTX5014: Caught exception in beforeCompletion() callback:
Local Exception Stack:
INFO: [EL Warning]: 2012-12-28 10:53:38.127--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERRO: atualização ou exclusão em tabela "person" viola restrição de chave estrangeira "fk_request_person_id" em "request"
Detalhe: Chave (id)=(111) ainda é referenciada pela tabela "request".
Error Code: 0
Call: DELETE FROM PERSON WHERE (ID = ?)
bind => [111]
Query: DeleteObjectQuery(111)
[...]
SEVERE: javax.ejb.EJBException: Transaction aborted
[...]

那么,当级联删除失败时,如何取消客户删除呢?

【问题讨论】:

  • 您的数据库连接是否设置为自动提交?如果没有,请向我们展示您的交易边界。
  • 这可能是问题所在。我使用 Oracle 10g 连接测试了应用程序,并且 回滚工作(我需要应用程序与这两个数据库 - Oracle 10g 和 Postgres 8.4 一起工作)。事务在无状态 Bean 上,边界是 JTA 的默认值(必需)。根据此链接stackoverflow.com/questions/13837146/…,无法禁用 Postgres 8.4(我正在使用)自动提交。也许我必须使用 bean 管理的事务?
  • 边界是指事务的开始和结束 - 无论如何,如果它与 Oracle 一起工作,问题是数据库(连接)。请发布连接设置。
  • 是的,我使用注释。我使用具有默认属性的 JTA 连接池。您能否更具体地了解连接设置?
  • 把我的 cmets 变成了一个真正的答案,因为这越来越长了。

标签: jpa transactions ejb cascade jta


【解决方案1】:

这里有两件事可能会出错。

  • 未正确指定事务边界

可能由于这个原因,您的应用程序服务器没有正确发出 BEGIN 语句。这可以解释 Postgres 有问题,而 Oracle 没有(它隐式启动事务)。确保您的服务方法带有正确的注释。如果一切都好,也许

  • 您的数据源有问题。

它是 JTA 兼容的数据源吗?它是否使用正确的 Postgres 驱动程序?请发布您的配置,以便我们检查。

我发现了一个有趣的链接,它也可能对您有所帮助。这是关于 Postgres 保持自动提交模式(尽管使用 Spring 时):

http://archives.postgresql.org/pgsql-jdbc/2007-07/msg00115.php

【讨论】:

  • 在 Glassfish 上的 JDBC 连接池属性上使用 defaultAutocommit = false(如您发布的链接中所述)解决了该问题。我使用的是 PostgreSQL 8.4.15 和 postgresql-8.4-703.jdbc4.jar 驱动程序。
  • 好的,我将调整答案,以便进一步的读者清楚解决方案是什么。你能说你用的是哪个类吗?简单我们的 PoolableDatasource?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-15
  • 2014-03-09
  • 2012-11-21
相关资源
最近更新 更多