簡體   English   中英

有什么區別:使用 JPA @TableGenerator、@GeneratedValue 與數據庫 Auto_Increment 的序列 ID

[英]What are the difference between: sequence id using JPA @TableGenerator, @GeneratedValue vs database Auto_Increment

Q1。 :在數據庫中應用序列 Id 與使用之間有什么區別

一種。

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的並發問題,我將不勝感激。 這是他們解決方案的一個片段:

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是否也會遇到同樣的問題?

使用 TableGenerator,下一個 id 值將在表中查找和維護,基本上由 JPA 而不是您的數據庫維護。 當您有多個線程訪問您的數據庫並試圖找出 id 字段的下一個值可能是什么時,這可能會導致並發問題。

auto_increment 類型將使您的數據庫關注表的下一個 id,即。 它將在運行插入時由數據庫服務器自動確定 - 這肯定是並發安全的。

更新:

有什么東西讓您無法使用 GenerationType.AUTO 嗎?

GenerationType.AUTO 確實 select 以適當的方式檢索您的實體的 ID。 所以在最好的情況下使用內置功能。 但是,您需要檢查生成的 SQL 並查看那里究竟發生了什么——因為 MSSQL 不提供序列,我假設它會使用 GenerationType.IDENTITY。

如前所述,auto_increment 列負責分配下一個 id 值,即。 那里沒有並發問題——即使有多個線程並行處理數據庫。 挑戰在於將此功能傳輸給 JPA 使用。

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

B:使用 TABLE id 生成

JPA支持IDENTITY, SEQUENCE and TABLE.

兩者都需要權衡取舍。

IDENTITY不允許預分配,所以每次INSERT后都需要額外的SELECT,防止批量寫入,訪問id需要flush,導致並發性差。

TABLE 允許預分配,但可能存在序列表上的鎖的並發問題。

從技術上講,SEQUENCE id 生成是最好的,但並非所有數據庫都支持它。

對於 TABLE 排序,如果您使用 100 的預分配大小,那么只有每 100 次插入才會鎖定序列表中的行,因此只要您通常不會同時有 100 次插入,您就不會遭受任何損失並發。 如果您的應用程序執行大量插入操作,則可以使用 1000 或更大的值。

EclipseLink 將使用單獨的事務進行 TABLE 排序,因此將減少任何與序列表鎖相關的並發問題。 如果您使用的是 JTA,那么您需要指定一個非 jta 數據源來執行此操作,並在您的 persistence.xml 屬性中配置一個序列連接池。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM