java - : sequence id using JPA @TableGenerator, @GeneratedValue 与数据库 Auto_Increment 之间有什么区别

标签 java sql sql-server jpa eclipselink

问题 1.:在数据库中使用序列 ID 有什么区别

A.

CREATE TABLE Person
(
   id long NOT NULL AUTO_INCREMENT
   ...
   PRIMARY KEY (id)
)

对比

B.

@Entity
public class Person {
    @Id
    @TableGenerator(name="TABLE_GEN", table="SEQUENCE_TABLE", pkColumnName="SEQ_NAME",
        valueColumnName="SEQ_COUNT", pkColumnValue="PERSON_SEQ")
    @GeneratedValue(strategy=GenerationType.TABLE, generator="TABLE_GEN")
    private long id;
    ...
}

我的系统高度并发。由于我的数据库是 Microsoft SQL 服务器,我认为它不支持 @SequenceGenerator,所以我必须继续使用 @TableGenerator,这很容易出现并发问题。

Q2. 此链接(http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Advanced_Sequencing)表明 B 可能会遇到并发问题,但我不理解建议的解决方案。如果有人能向我解释如何避免 B 的并发问题,我将不胜感激。这是他们解决方案的一个片段:

如果使用较大的序列预分配大小,这就不是一个问题,因为序列表很少被访问。

Q2.1:我们在这里讨论的分配大小是多少?我应该做 allocationSize=10 还是 allocationSize=100

某些 JPA 提供程序使用单独的(非 JTA)连接来分配序列 ID,从而避免或限制此问题。在这种情况下,如果您使用 JTA 数据源连接,那么在您的 persistence.xml 中也包含一个非 JTA 数据源连接很重要。

Q2.2:我使用 EclipseLink 作为我的提供商;我必须按照上面的建议去做吗?

Q3.如果 B 遇到并发问题,A 是否也会遇到同样的问题?

最佳答案

使用 TableGenerator,下一个 id 值将在表中查找和维护,基本上由 JPA 维护,而不是您的数据库。当您有多个线程访问您的数据库并试图找出 id 字段的下一个值可能是什么时,这可能会导致并发问题。

auto_increment 类型将使您的数据库关注表的下一个 ID,即。它将在运行插入时由数据库服务器自动确定 - 这肯定是并发安全的。

更新:

是否有什么让您无法使用 GenerationType.AUTO?

GenerationType.AUTO 确实选择了一种适当的方式来检索您的实体的 ID。所以在最好的情况下使用内置功能。但是,您需要检查生成的 SQL 并查看那里究竟发生了什么——因为 MSSQL 不提供序列,我假设它会使用 GenerationType.IDENTITY。

正如所说,auto_increment 列负责分配下一个 id 值,即。那里没有并发问题——即使有多个线程并行处理数据库。挑战在于将此功能转移到 JPA 中使用。

关于java - : sequence id using JPA @TableGenerator, @GeneratedValue 与数据库 Auto_Increment 之间有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10033727/

相关文章:

java - 使用 native Java JCE 验证 PC 上 Bouncy CaSTLe 生成的签名

java - LibGdx Java 中不显示文本

java - Spring bean container <import> 命令是否消除了重复的容器?

sql - 如果引用父 ID 的所有子项都已选择值,则返回父 ID

sql - SQL Server 中的 DateTime2 与 DateTime

sql-server - 在 Azure DevOps 中构建 SSIS 项目时出现 System.ArgumentException。在本地工作

sql - 在 SQL Server 中删除日期时间的时间部分的最佳方法

java - 如何在 Android MVVM 虚拟机中模拟父子关系?

sql - 多语言数据库设计的最佳实践是什么?

mysql - 如何在没有错误的列上创建全文索引