java 有什么区别:序列 id 使用 JPA @TableGenerator、@GeneratedValue 与数据库 Auto_Increment
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10033727/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are the difference between: sequence id using JPA @TableGenerator, @GeneratedValue vs database Auto_Increment
提问by Thang Pham
Q1.: What is the difference between applying sequence Id in a database using
一季度。:在数据库中使用序列 ID 有什么区别
A.
一个。
CREATE TABLE Person
(
id long NOT NULL AUTO_INCREMENT
...
PRIMARY KEY (id)
)
versus
相对
B.
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;
...
}
My system is highly concurrent. Since my DB is a Microsoft SQL server, I do not think it supports @SequenceGenerator
, so I have to stay with @TableGenerator
which is prone to concurrency issues.
我的系统是高度并发的。由于我的数据库是 Microsoft SQL 服务器,我认为它不支持@SequenceGenerator
,所以我必须坚持使用@TableGenerator
它,容易出现并发问题。
Q2.This link here (http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Advanced_Sequencing) suggests that Bmight suffer from concurrency issues, but I do not understand the proposed solution. I would greatly appreciate it if someone could explain to me how to avoid concurrency issues with B. Here is a snippet of their solution:
Q2。此处的链接 ( http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Advanced_Sequencing) 表明B可能会遇到并发问题,但我不理解建议的解决方案。如果有人能向我解释如何避免B 的并发问题,我将不胜感激。这是他们解决方案的一个片段:
If a large sequence pre-allocation size is used this becomes less of an issue, because the sequence table is rarely accessed.
If a large sequence pre-allocation size is used this becomes less of an issue, because the sequence table is rarely accessed.
Q2.1: How much allocation size are we talking about here? Should I do allocationSize=10
or allocationSize=100
?
Q2.1: 我们在这里谈论的分配大小是多少?我应该做allocationSize=10
还是allocationSize=100
?
Some JPA providers use a separate (non-JTA) connection to allocate the sequence ids in, avoiding or limiting this issue. In this case, if you use a JTA data-source connection, it is important to also include a non-JTA data-source connection in your persistence.xml.
Some JPA providers use a separate (non-JTA) connection to allocate the sequence ids in, avoiding or limiting this issue. In this case, if you use a JTA data-source connection, it is important to also include a non-JTA data-source connection in your persistence.xml.
Q2.2: I use EclipseLink as my provider; do I have to do what it suggests above?
Q2.2:我使用 EclipseLink 作为我的提供者;我必须按照上面的建议去做吗?
Q3.If Bsuffers from concurrency issues, does Asuffer the same?
Q3。如果B有并发问题,A 也有同样的问题吗?
回答by PepperBob
Using a TableGenerator the next id value will be looked up and maintained in a table and basically maintained by JPA and not your database. This may lead to concurrency issue when you have multiple threads accessing your database and trying to figure out what the next value for the id field may be.
使用 TableGenerator 下一个 id 值将在表中查找和维护,并且基本上由 JPA 而不是您的数据库维护。当您有多个线程访问您的数据库并试图找出 id 字段的下一个值可能是什么时,这可能会导致并发问题。
The auto_increment type will make your database take care about the next id of your table, ie. it will be determined automatically by the database server when running the insert - which surely is concurrency safe.
auto_increment 类型将使您的数据库照顾您的表的下一个 id,即。运行插入时,它将由数据库服务器自动确定 - 这肯定是并发安全的。
Update:
更新:
Is there something that keeps you away from using GenerationType.AUTO?
有什么让您无法使用 GenerationType.AUTO 吗?
GenerationType.AUTO does select an appropriate way to retrieve the id for your entity. So in best case in uses the built-in functionality. However, you need to check the generated SQLs and see what exactly happens there - as MSSQL does not offer sequences I assume it would use GenerationType.IDENTITY.
GenerationType.AUTO 确实选择了一种适当的方式来检索您的实体的 id。所以在最好的情况下使用内置功能。但是,您需要检查生成的 SQL 并查看那里究竟发生了什么 - 因为 MSSQL 不提供序列,我认为它会使用 GenerationType.IDENTITY。
As said the auto_increment column takes care about assigning the next id value, ie. there is no concurrency issue there - even with multiple threads tackling the database in parallel. The challenge is to transfer this feature to be used by JPA.
如前所述, auto_increment 列负责分配下一个 id 值,即。那里没有并发问题 - 即使有多个线程并行处理数据库。挑战是转移此功能以供 JPA 使用。
回答by James
A: uses IDENTITY id generation, @GeneratedValue(IDENTITY)
A:使用IDENTITY id生成, @GeneratedValue(IDENTITY)
B: uses TABLE id generation
B: 使用 TABLE id 生成
JPA supports three types, IDENTITY, SEQUENCE and TABLE.
JPA支持三种类型, IDENTITY, SEQUENCE and TABLE.
There are trade-offs with both.
两者都有取舍。
IDENTITY does not allow preallocation, so requires an extra SELECT after every INSERT, prevents batch writing, and requires a flush to access the id which may lead to poor concurrency.
IDENTITY 不允许预分配,因此在每次 INSERT 后都需要一个额外的 SELECT,防止批量写入,并且需要刷新来访问可能导致并发性差的 id。
TABLE allows preallocation, but can have concurrency issues with locks on the sequence table.
TABLE 允许预分配,但可能存在序列表上的锁的并发问题。
Technically SEQUENCE id generation is the best, but not all databases support it.
从技术上讲 SEQUENCE id 生成是最好的,但并非所有数据库都支持它。
With TABLE sequencing if you use a preallocaiton size of 100, then only every 100 inserts will lock the row in the sequence table, so as long as you don't commonly have 100 inserts at the same time, you will not suffer any loss in concurrency. If you application does a lot of inserts, maybe use 1000 or larger value.
使用 TABLE 排序如果您使用 100 的预分配大小,那么只有每 100 次插入才会锁定序列表中的行,因此只要您通常不会同时有 100 次插入,您就不会遭受任何损失并发。如果您的应用程序进行了大量插入,则可能使用 1000 或更大的值。
EclipseLink will use a separate transaction for TABLE sequencing, so any concurrency issue with locks to the sequence table will be reduced. If you are using JTA, then you need to specify a non-jta-datasource to do this and configure a sequence-connection-pool in your persistence.xml properties.
EclipseLink 将使用单独的事务进行 TABLE 排序,因此将减少任何与锁定序列表有关的并发问题。如果您正在使用 JTA,那么您需要指定一个非 jta-datasource 来执行此操作并在您的 persistence.xml 属性中配置一个序列连接池。