问题 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/