Подтвердить что ты не робот

В чем разница между идентификатором последовательности с использованием JPA @TableGenerator, @GeneratedValue и базы данных Auto_Increment

Q1.: В чем разница между применением идентификатора последовательности в базе данных с помощью

а.

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

против

В.

@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, который подвержен проблемам concurrency.

Q2. Эта ссылка здесь (http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Advanced_Sequencing) предполагает, что B может пострадать от concurrency но я не понимаю предлагаемого решения. Я был бы очень признателен, если бы кто-нибудь мог объяснить мне, как избежать проблем concurrency с 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 страдает от проблем concurrency, имеет ли A то же самое?

4b9b3361

Ответ 1

Используя TableGenerator, следующее значение id будет проверяться и поддерживаться в таблице и в основном поддерживается JPA, а не вашей базой данных. Это может привести к ошибке concurrency, когда у вас есть несколько потоков, обращающихся к вашей базе данных и пытающихся выяснить, что может быть следующим значением для поля id.

Тип auto_increment заставит вашу базу данных заботиться о следующем id вашей таблицы, т.е. он будет автоматически определяться сервером базы данных при запуске вставки, что, безусловно, является concurrency безопасным.

Update:

Есть ли что-то, что мешает вам использовать GenerationType.AUTO?

GenerationType.AUTO действительно выбирает подходящий способ для получения идентификатора для вашего объекта. Поэтому в лучшем случае используется встроенная функциональность. Однако вам нужно проверить сгенерированные SQL-запросы и посмотреть, что именно там происходит - поскольку MSSQL не предлагает последовательности, я предполагаю, что он будет использовать GenerationType.IDENTITY.

Как сказано, столбец auto_increment заботится о назначении следующего значения id, т.е. там нет проблемы concurrency - даже с несколькими потоками, параллельно использующими базу данных. Задача состоит в передаче этой функции, которая будет использоваться JPA.

Ответ 2

A: используется генерация идентификатора IDENTITY, @GeneratedValue (IDENTITY)

B: использует генерацию TABLE id

JPA поддерживает три типа: IDENTITY, SEQUENCE и TABLE.

Есть компромиссы с обоими.

ИДЕНТИФИКАЦИЯ не разрешает предварительное выделение, поэтому требуется дополнительный SELECT после каждого INSERT, предотвращает пакетную запись и требует сброса для доступа к id, что может привести к плохим concurrency.

TABLE допускает предварительное распределение, но может иметь concurrency проблемы с блокировками в таблице последовательностей.

Технически генерация идентификаторов SEQUENCE является лучшей, но не все базы данных поддерживают ее.

С помощью последовательности TABLE, если вы используете размер preallocaiton 100, тогда только каждые 100 вложений будут блокировать строку в таблице последовательности, так что, пока вы обычно не используете 100 вставок одновременно, вы не будете страдать любая потеря в concurrency. Если в приложении много вставок, возможно, используйте значение 1000 или больше.

EclipseLink будет использовать отдельную транзакцию для последовательности TABLE, поэтому любая проблема concurrency с блокировками в таблице последовательности будет уменьшена. Если вы используете JTA, вам нужно указать источник non-jta-datasource для этого и настроить пул соединений-соединений в свойствах persistence.xml.