【问题标题】:How to determine if an Oracle deferrable constraint violation occurred in JPA?如何确定 JPA 中是否发生了 Oracle 可延迟约束违规?
【发布时间】:2012-01-25 10:19:40
【问题描述】:

如果事务违反延迟约束,Oracle 11g 会在提交时静默回滚事务。实际得到错误的一种方法是在调用 commit 之前将约束设置为 immediate。使用 Oracle SQL Developer 可以正常工作,但是在 JPA (EclipseLink) 本机查询中执行此操作会导致应用程序锁定。如果违反了延迟约束,是否有其他方法可以通知?或者我没有正确使用 JPA?

表定义:

create table foo
(
foo_id integer not null,
order_id integer not null,
constraint foo_pk primary key (foo_id),
constraint foo_ak unique (order_id) deferrable
);

SQL 生成违规并查看控制台上显示的错误:

set constraint foo_ak deferred;
insert into foo values (1, 1);
insert into foo values (2, 1);
set constraint foo_ak immediate; -- Will rollback and display error

JPA 试图重新排序无状态会话 Bean 中的 foo 实体集合:

public void edit(List<Foo> foos) {
    Query deferred = em.createNativeQuery("set constraint foo_ak deferred");
    Query immediate = em.createNativeQuery("set constraint foo_ak immediate");

    deferred.executeUpdate(); // This works

    for(Foo f: foos) {
        em.merge(f); // This works too
    }

    immediate.executeUpdate(); // Hang with no output!
    // Note: if I comment out above line the transaction may 
    // be silently rolled back on deferred constraint violation
}

【问题讨论】:

  • 看起来 Oracle 11gR1 和 11gR2 处理延迟约束的方式不同。我有 R1 并且看到了静默回滚行为。我读过一篇描述 R2 中的 bug 的文章,它表明 (1) 一个 bug,并且 (2) R2 不执行静默回滚:pythian.com/news/9881/…

标签: oracle jpa


【解决方案1】:

问题可能出在语句缓存和应用服务器事务策略中。

尝试:

  • 在 {} 执行后通过调用 em.flush() 强制实体管理器将数据发送到数据库

和/或

  • 在您的方法中将@TransactionManagement 属性更改为bean 管理和管理事务

【讨论】:

  • 我最终放弃了设置约束语句方法,但使用刷新或手动管理事务可能会起作用。不知道为什么或发生了什么变化,但现在当违反延迟约束时,我在事务结束时抛出异常(这是我一直想要的)。也许我有缓存问题?无论如何,感谢您花时间回答我的问题。
猜你喜欢
  • 2012-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2019-10-28
  • 2020-04-19
  • 2019-04-08
  • 1970-01-01
相关资源
最近更新 更多