![](/img/trans.png)
[英]How to set an id auto_increment with JPA and without using an oracle sequence
[英]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.