2012-04-05 123 views
13

Q1。:是什麼使用有什麼區別:使用JPA @TableGenerator,@GeneratedValue和數據庫的序列ID Auto_Increment

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

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。如果從併發的問題而下降,並一個遭受一樣的嗎?

回答

14

使用TableGenerator值的下一個ID會被擡起頭,保持在表基本上是由JPA,而不是你的數據庫維護。當您有多個線程訪問您的數據庫並試圖找出id字段的下一個值可能是什麼時,這可能會導致併發問題。

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

更新:

有什麼,讓你遠離使用GenerationType.AUTO?

GenerationType.AUTO會選擇合適的方式來檢索實體的ID。所以在最好的情況下使用內置功能。但是,你需要檢查生成的sql語句,看看到底發生了什麼那裏 - 因爲MSSQL不提供我相信它會使用GenerationType.IDENTITY序列。

至於說AUTO_INCREMENT列大約需要分配值的下一個ID,即照顧。那裏沒有併發問題 - 即使多個線程並行處理數據庫也是如此。我們面臨的挑戰是將這個特性傳遞給JPA使用。

+0

當你說:'我們面臨的挑戰是轉移此功能通過JPA.'使用,你指的是使用'@ GeneratedValue'的?所以我嘗試設置表'AUTO_INCREMENT'中的列,然後嘗試創建多個'Person'。第一個使用'id'正確創建的人開始是5,但是它爲2生成了一個例外。'在工作單元克隆中遇到空或零主鍵。我們不能只用'@ Id'註釋id,沒有'@ GeneratedValue',然後堅持實體對象,讓'AUTO_INCREMENT' PK數據庫來照顧它? – 2012-04-11 20:13:47

+0

你可以顯示你的映射嗎?您應該使用'@ GeneratedValue'來告訴JPA實現該ID是否被處理。這裏有一個鏈接可以幫助您:http://www.developerscrappad.com/408/java/java-ee/ejb3-jpa-3-ways-of-generating-primary-key-through-generatedvalue/ – 2012-04-16 12:58:47

11

一個:使用標識ID的生成,@GeneratedValue(IDENTITY)

B:使用表ID代

JPA支持三種類型,IDENTITY,SEQUENCE和表。

這兩者都有折衷。

IDENTITY不允許預分配,所以要求每個INSERT後,一個額外的選擇,防止批量寫入,並需要刷新訪問,這可能導致併發性差的ID。

TABLE允許預分配,但可以有與序列表鎖併發問題。

技術上序列ID生成是最好的,但不是所有的數據庫都支持它。

使用TABLE排序如果您使用preallocaiton大小爲100,那麼只有每100個插入將會鎖定序列表中的行,所以只要您通常不會同時存在100個插入,您就不會在併發中遭受任何損失。如果你的應用程序做了很多插入,也許使用1000或更大的值。

的EclipseLink將使用TABLE測序一個單獨的事務,所以用鎖序列表中的任何併發問題就會減少。如果您使用的是JTA,那麼您需要指定一個非jta-datasource來執行此操作,並在persistence.xml屬性中配置一個序列連接池。

+0

您的信息關於'TABLE排序preallocaiton大小'幫助我很多,因爲我決定使用'TABLE'序列來執行。你應該有這個獎勵,我會等一會兒,看看有沒有人有任何其他想法貢獻,如果沒有,我會給你賞金。非常感謝你 – 2012-04-11 20:26:12

相關問題