2012-04-05 10 views
13

Q1.: Jaka jest różnica między zastosowaniem sekwencji ID w bazie danych przy użyciuJaka jest różnica między: id sekwencji przy użyciu JPA @TableGenerator, @GeneratedValue vs database Auto_Increment

A.

CREATE TABLE Person 
(
    id long NOT NULL AUTO_INCREMENT 
    ... 
    PRIMARY KEY (id) 
) 

kontra

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; 
    ... 
} 

Mój system jest wysoce współbieżne. Ponieważ mój DB jest serwerem Microsoft SQL, nie sądzę, że obsługuje on @SequenceGenerator, więc muszę pozostać przy @TableGenerator, który jest podatny na problemy współbieżności.

Q2. Ten odnośnik tutaj (http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Advanced_Sequencing) sugeruje, że B może cierpieć z powodu problemów z współbieżnością, ale nie rozumiem proponowanego rozwiązania. Byłbym bardzo wdzięczny, gdyby ktoś mógł mi wyjaśnić, jak uniknąć problemów z współbieżnością z B. Oto fragment ich rozwiązania:

If a large sequence pre-allocation size is used this becomes less of an issue, because the sequence table is rarely accessed.

Q2.1: Ile wielkość alokacji mówimy tutaj? Czy powinienem wykonać allocationSize=10 lub 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: Używam EclipseLink jako mojego dostawcy; czy muszę zrobić to, co sugeruje powyżej?

Q3. Jeśli wystąpią problemy z współbieżnością, B cierpi na to samo?

Odpowiedz

14

Przy użyciu TableGenerator, następna wartość id zostanie sprawdzona i utrzymana w tabeli i zasadniczo utrzymywana przez JPA, a nie przez twoją bazę danych. Może to prowadzić do problemu współbieżności, gdy masz wiele wątków uzyskujących dostęp do bazy danych i próbuje dowiedzieć się, jaka może być następna wartość dla pola identyfikatora.

Typ auto_increment sprawi, że baza danych zadba o następny identyfikator Twojej tabeli, czyli. zostanie to określone automatycznie przez serwer bazy danych podczas uruchamiania wkładki - która z pewnością jest bezpieczna dla współbieżności.

Aktualizacja:

Czy istnieje coś, co trzyma z dala od używania GenerationType.AUTO?

GenerationType.AUTO wybiera odpowiedni sposób pobrania identyfikatora dla jednostki. Tak więc w najlepszym razie używa wbudowanej funkcjonalności. Musisz jednak sprawdzić wygenerowane SQL i zobaczyć, co dokładnie się tam dzieje - ponieważ MSSQL nie oferuje sekwencji, zakładam, że użyłby GenerationType.IDENTITY.

Tak jak powiedział kolumna auto_increment dba o przypisanie następnej wartości id, czyli. tam nie ma problemu z współbieżnością - nawet z wieloma wątkami, które atakują bazę danych równolegle. Wyzwanie polega na przeniesieniu tej funkcji do wykorzystania przez JPA.

+0

Kiedy powiedziałeś: "Wyzwaniem jest przeniesienie tej funkcji, która ma być używana przez WZP.", Czy odnosisz się do użycia '@ GeneratedValue'? Tak więc próbuję ustawić kolumnę w tabeli 'AUTO_INCREMENT', a następnie spróbuję stworzyć wielokrotność' Osoba'. Pierwsza osoba tworzy poprawnie z "id" zaczyna się na 5, ale generuje wyjątek dla osoby 2. 'Null lub zero klucz podstawowy napotkany w jednostce pracy clone. Czy nie możemy po prostu zanotować identyfikatora za pomocą '@ Id', bez' @ GeneratedValue', a następnie utrzymywać obiekt encji i pozwolić, aby baza danych z 'AUTO_INCREMENT' PK zajmowała się tym? –

+0

Czy możesz pokazać swoje mapowanie? Powinieneś użyć '@ GeneratedValue', aby powiedzieć implementacji JPA, że dbano o identyfikator. Oto jeden link, który pomoże Ci przejść dalej: http://www.developerscrappad.com/408/java/java-ee/ejb3-jpa-3-ways-of-generating-primary-key-through-generatedvalue/ –

11

A: wytwarzanie wykorzystuje identyfikator IDENTITY, @GeneratedValue (tożsamości)

B: stosuje TABELA generacji identyfikatora

JPA obsługuje trzy typy, tożsamość sekwencji i Tabeli.

Istnieją kompromisy z oboma.

TOŻSAMOŚĆ nie pozwala na wstępną alokację, dlatego po każdym INSERT wymaga dodatkowego WYBORU, zapobiega pisaniu wsadowym i wymaga spłukiwania dostępu do identyfikatora, co może prowadzić do niskiej współbieżności.

TABELA umożliwia wcześniejsze przydzielenie, ale może mieć problemy z współbieżnością z blokadami w tabeli sekwencji.

Technicznie SEQUENCE id generation to najlepsze, ale nie wszystkie bazy danych obsługują go.

Przy sekwencjonowaniu TABELI, jeśli użyjesz rozmiaru prealocaiton równego 100, to tylko co 100 wstawek zablokuje wiersz w tabeli sekwencji, więc dopóki nie będziesz miał zwykle 100 wkładek w tym samym czasie, nie będziesz cierpią na jakąkolwiek utratę współbieżności. Jeśli aplikacja wykonuje wiele wstawek, może użyć wartości 1000 lub większej.

EclipseLink użyje oddzielnej transakcji do sekwencjonowania TABELI, więc wszelkie problemy z współbieżnością z blokadami do tabeli sekwencji zostaną zmniejszone. Jeśli korzystasz z JTA, musisz określić źródło danych inne niż jta i skonfigurować pulę połączeń sekwencji we właściwościach persistence.xml.

+0

Twoje informacje o "Sekwencjonowaniu tabele rozmiar prealocaiton" mi pomóc, jak zdecyduję się użyć sekwencji 'TABLE' dla mojej realizacji. Powinieneś mieć tę nagrodę, poczekam trochę więcej, aby sprawdzić, czy ktoś ma jakikolwiek inny pomysł, aby wnieść wkład, jeśli nie, dam ci nagrodę. Dziękuję Ci bardzo –