【发布时间】:2014-12-17 16:15:06
【问题描述】:
我正在使用 EclipseLink 2.4.2(与 Spring 结合使用,但我认为这与我们这里的问题无关)并且我们有几次出现以下异常:
org.springframework.transaction.TransactionSystemException:无法提交 JPA 事务;嵌套异常是 javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.2.v20130514-5956486): org.eclipse.persistence.exceptions.DatabaseException
内部异常:java.sql.SQLIntegrityConstraintViolationException:ORA-00001:违反了唯一约束 (****.PK_*****)
我们的主键是由 EclipseLink 生成的,它使用 Oracle 序列来分配它们。我仔细检查了,allocationSize 与序列中定义的increment by 完全匹配。
下面是如何在我们的 Java 类中定义此序列的示例:
@Id
@SequenceGenerator(name = "SOME_GENERATOR", sequenceName = "SOME_SEQ", allocationSize = 10000, initialValue = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SOME_GENERATOR")
@Column(name = "ID")
private Long id;
这里是创建序列的 SQL 语句:
CREATE SEQUENCE SOME_SEQ INCREMENT BY 10000 START WITH 10000;
当然,这个问题很难重现,只是随机发生。当服务器负载过重时,这种情况似乎更频繁地发生。
我不知道这是否相关,但这里有一些额外的信息:
- 我们有两台服务器访问同一个数据库
- 主键定义被许多类继承
我的第一个想法是这与并发有关,但对于这样一个成熟的框架来说,这似乎是一个相当严重的问题。还有什么我应该验证或我可能忽略的事情吗?
我看过相关的帖子,比如这些帖子:
- use of EntityManagerFactory causing duplicate primary key exceptions
- Persistence errors using @GeneratedValue for primary key
- JPA throws no EntityExistsException but generates a duplicate row (auto generated PK)
但它们似乎对我没有帮助。
【问题讨论】:
-
你能确定用于失败语句的值,以及数据库中序列的值吗?
-
@Chris 不幸的是没有。这些错误仅在我们运行并行运行的自动化测试时发生。 SQL 参数记录被禁用。我不确定获得这些值是否会帮助我找到问题。但是,如果您对我如何从这些值中追溯错误(在我的代码或 EL 中)有指导意见,我会非常感兴趣。
-
没有什么特别的,只是寻求任何可以帮助找出使用相同编号的两个进程的特殊之处以及它们是如何获得的信息
-
@Chris 我们实际上设法发现了错误是如何发生的。问题来自“Reset of DB”和 EclipseLink 预分配 id 的错误组合。
标签: java oracle jpa eclipselink