«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Когда и почему следует корректировать параметры изоляции и распространения по умолчанию в @Transactional?

Когда и почему следует корректировать параметры изоляции и распространения по умолчанию в @Transactional?

Опубликовано 6 ноября 2024 г.
Просматривать:695

When and Why Should You Adjust the Default Isolation and Propagation Parameters in @Transactional?

Параметры изоляции и распространения в @Transactional

В аннотации @Transactional Spring два критических параметра определяют поведение транзакций базы данных: изоляция и распространение . В этой статье рассказывается, когда и почему вам следует рассмотреть возможность изменения их значений по умолчанию.

Распространение

Распространение определяет, как транзакции связаны друг с другом. Общие параметры включают в себя:

  • ОБЯЗАТЕЛЬНО: Запускает код в рамках существующей транзакции или создает новую, если таковой не существует.
  • REQUIRES_NEW: Всегда создает новую транзакцию, приостанавливая все существующие.

Значение по умолчанию: ТРЕБУЕТСЯ

Изоляция

Изоляция определяет контракт данных между транзакциями. Он предотвращает определенные несоответствия данных, определяя уровень видимости изменений данных, внесенных другими транзакциями. Ключевые уровни изоляции:

  • READ_UNCOMMITTED: Нет защиты от грязного чтения.
  • SERIALIZABLE: Самая сильная изоляция, гарантирующая отсутствие конфликтов данных.

Значение по умолчанию: Зависит от базы данных (например, REPEATABLE_READ для MariaDB)

Пример из реальной жизни

Рассмотрим проблему грязного чтения, когда транзакция может читать незафиксированные изменения, внесенные другой транзакцией.

                                       Thread 1          Thread 2
                                               |              |
                                             Write(x)           |
                                               |              |
                                               |             Read(x)
                                               |              |
                                             Rollback           |
                                                 |             |
                                                   Value (x) is now dirty (incorrect)

В этом сценарии, чтобы предотвратить «грязное» чтение, вы можете установить уровень изоляции на READ_COMMITTED и уровень распространения на REQUIRED. Эта комбинация гарантирует, что транзакции считывают только данные, зафиксированные другими транзакциями.

Настройка транзакций

В следующем примере метод provideService всегда выполняется внутри новой транзакции, гарантируя, что любые изменения, внесенные другими параллельными задачами, не мешают ее выполнению:

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void provideService() {
    repo1.retrieveFoo();
    repo2.retrieveFoo();
}

Тестирование поведения транзакции

Чтобы проверить поведение различных уровней распространения, вы можете использовать тест Java:

@Test
public void testProvideService() {
    TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
    fooService.provideService();
    transactionManager.rollback(status);
    // Assert repository values are unchanged ...
}

При использовании REQUIRES_NEW, fooService.provideService() не будет откачен, поскольку он работает в рамках отдельной транзакции. С помощью REQUIRED все будет отменено.

Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3