首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用JPA @TableGenerator、@GeneratedValue和数据库Auto_Increment的序列id有什么区别?

使用JPA @TableGenerator、@GeneratedValue和数据库Auto_Increment的序列id有什么区别?
EN

Stack Overflow用户
提问于 2012-04-05 18:09:42
回答 2查看 13.3K关注 0票数 15

Q1.:在数据库中使用

A.

代码语言:javascript
复制
CREATE TABLE Person
(
   id long NOT NULL AUTO_INCREMENT
   ...
   PRIMARY KEY (id)
)

B.

代码语言:javascript
复制
@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服务器,所以我认为它不支持@SequenceGenerator,所以我不得不使用@TableGenerator,这很容易出现并发问题。

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.

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.

Q2.2:我使用EclipseLink作为我的提供者;我必须做上面建议的事情吗?

Q3.如果B存在并发问题,那么A也会遇到同样的问题吗?

EN

回答 2

Stack Overflow用户

发布于 2012-04-09 15:11:05

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

auto_increment类型将使数据库负责表的下一个id,即。它将由数据库服务器在运行insert时自动确定,这肯定是并发安全的。

更新:

有什么东西可以阻止你使用GenerationType.AUTO吗?

GenerationType.AUTO确实选择了一种适当的方法来检索实体的id。因此,在最好的情况下,使用内置的功能。但是,您需要检查生成的SQL并查看那里到底发生了什么--因为MSSQL没有提供我假设它将使用GenerationType.IDENTITY的序列。

如前所述,auto_increment列负责分配下一个id值,即。那里没有并发问题--即使多个线程并行地处理数据库。现在的挑战是将这个特性传递给JPA。

票数 15
EN

Stack Overflow用户

发布于 2012-04-10 14:59:14

A:使用标识标识生成,@GeneratedValue(IDENTITY)

B:使用表id生成

JPA支持三种类型,IDENTITY, SEQUENCE and TABLE.

两者都有取舍。

IDENTITY不允许预分配,因此每次插入后都需要额外的选择,防止批量写入,并且需要刷新才能访问id,这可能导致并发性差。

表允许预分配,但可能与序列表上的锁存在并发问题。

从技术上讲,序列id生成是最好的,但并非所有数据库都支持它。

对于表排序,如果您使用100的预分配子大小,那么只有每100个插入将锁定序列表中的行,因此只要您通常不同时拥有100个插入,您就不会在并发方面遭受任何损失。如果应用程序执行了大量插入操作,则可能使用1000或更大的值。

EclipseLink将使用一个单独的事务来进行表排序,因此,与序列表的锁相关的任何并发问题都将减少。如果您正在使用JTA,那么您需要指定一个非jta数据源来做到这一点,并在您的persistence.xml属性中配置一个序列连接池。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10033727

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档