English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
В управлении транзакциями Spring Boot реализуется интерфейс PlatformTransactionManager.
public interface PlatformTransactionManager { org.springframework.transaction.TransactionStatus getTransaction(org.springframework.transaction.TransactionDefinition transactionDefinition) throws org.springframework.transaction.TransactionException; void commit(org.springframework.transaction.TransactionStatus transactionStatus) throws org.springframework.transaction.TransactionException; void rollback(org.springframework.transaction.TransactionStatus transactionStatus) throws org.springframework.transaction.TransactionException; }
Когда мы используем зависимость spring-boot-starter-jdbc,框架 автоматически инъектирует DataSourceTransactionManager по умолчанию. Поэтому нам не нужно никакого дополнительного конфигурирования, чтобы использовать транзакцию с помощью аннотации @Transactional.
Менеджер транзакций JDBC
В Service, метод, помеченный аннотацией @Transactional, будет поддерживать транзакцию. Если аннотация находится на классе, то все методы класса по умолчанию поддерживают транзакцию.
Ситуация с несколькими менеджерами транзакций
Первый: можно реализовать интерфейс TransactionManagementConfigurer, где метод возвращает значение по умолчанию для управления транзакциями.
Второй: можно установить value на конкретном методе выполнения
Если в контейнере Spring существует несколько экземпляров PlatformTransactionManager и не реализован интерфейс TransactionManagementConfigurer для указания значения по умолчанию, при использовании аннотации @Transactional в методе, необходимо указать value, если не указать,则会 выбросить исключение.
// @EnableTransactionManagement // Включение аннотации управления транзакциями, эквивалент xml конфигурации <tx:annotation-driven /> @SpringBootApplication public class ProfiledemoApplication implements TransactionManagementConfigurer { @Resource(name="txManager2") private PlatformTransactionManager txManager2; // Ручное создание менеджера транзакций 1, datasource框架 будет автоматически инъектировать // В контейнере Spring, мы вручную аннотируем @Bean, и его будут загружены первыми,框架 не будет реинциализировать другие реализации PlatformTransactionManager. @Bean(name = "txManager1") public PlatformTransactionManager txManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } // Создание менеджера транзакций 2 @Bean(name = "txManager2") public PlatformTransactionManager txManager2(EntityManagerFactory factory) { return new JpaTransactionManager(factory); } // Реализация интерфейса TransactionManagementConfigurer, его возвращаемое значение представляет собой defaultManager для использования в случае наличия нескольких менеджеров транзакций @Override public PlatformTransactionManager annotationDrivenTransactionManager() { return txManager2; } public static void main(String[] args) { SpringApplication.run(ProfiledemoApplication.class, args); } }
Конкретная реализация
@Component public class DevSendMessage implements SendMessage { // Использование value для конкретного указания использования определенного менеджера транзакций @Transactional(value="txManager1") @Override public void send() { System.out.println(">>>>>>>>Dev Send()<<<<<<<<"); send2(); } @Transactional public void send2() { System.out.println(">>>>>>>>Dev Send2()<<<<<<<<"); } }
Изоляция уровня
public enum Isolation { DEFAULT(TransactionDefinition.ISOLATION_DEFAULT), READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED), READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED), REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ), SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE); private final int value; Isolation(int value) { this.value = value; } public int value() { return this.value; } }
Определение метода: через использование свойства isolation, например:
@Transactional(isolation = Isolation.DEFAULT)
Поведение передачи
Под поведением передачи транзакции понимается, что если до начала текущей транзакции уже существует контекст транзакции, то в этом случае есть несколько вариантов для определения поведения выполнения метода транзакции.
Мы можем увидеть, что в классе枚举 org.springframework.transaction.annotation.Propagation определены 6 значений, представляющих поведение передачи:
public enum Propagation { REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED), SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS), MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY), REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW), NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED), NEVER(TransactionDefinition.PROPAGATION_NEVER), NESTED(TransactionDefinition.PROPAGATION_NESTED); private final int value; Propagation(int value) { this.value = value; } public int value() { return this.value; } }
REQUIRED: если текущая транзакция существует, то добавляется к этой транзакции; если текущей транзакции нет, то создается новая транзакция. Значение по умолчанию.
SUPPORTS: если текущая транзакция существует, то добавляется к этой транзакции; если текущей транзакции нет, то продолжает работать в не транзакционном режиме.
MANDATORY: если текущая транзакция существует, то добавляется к этой транзакции; если текущей транзакции нет, то выбрасывается исключение (принудительно добавляется в транзакцию)
REQUIRES_NEW: создает новую транзакцию, если текущая транзакция существует, то текущую транзакцию приостанавливается (часто используется для записи журнала, даже если перед этим произошел откат, транзакция все равно будет выполнена, чтобы записать информацию об ошибке)
NOT_SUPPORTED: выполняется в не транзакционном режиме, если текущая транзакция существует, то текущую транзакцию приостанавливается.
NEVER: выполняется в не транзакционном режиме, если текущая транзакция существует, то выбрасывается исключение.
NESTED: если текущая транзакция существует, то создается транзакция в качестве вложенной транзакции текущей транзакции для выполнения; если текущей транзакции нет, то это значение эквивалентно REQUIRED.
Указанный метод: с помощью установки атрибута propagation, например:
@Transactional(propagation = Propagation.REQUIRED)
Ситуации, когда транзакция не будет откатываться
Р rolling back только в случае возникновения не捕获ленного RuntimeException
catch-вызванные исключения, оба вставки будут успешными
@Override @Transactional public void insertandinsert(Staff staff) { staffDao.insert(staff); try { int i = 1 / 0; }catch (Exception e){ e.printStackTrace(); } staffDao.insert(staff); }
В блоке catch метода уровня service добавьте предложение: TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); для ręcznego cofnięcia, что не позволит вставить данные
@Override @Transactional public void insertandinsert(Staff staff) throws Exception { try { staffDao.insert(staff); int i=1/0; staffDao.insert(staff); }catch (Exception e){ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } }
Это конец статьи, надеюсь, она поможет вам в изучении, также希望大家多多支持呐喊教程。
Заявление: содержимое этой статьи взято из Интернета, авторские права принадлежат соответствующему автору. Контент предоставлен пользователями Интернета, самостоятельно загружен, сайт не обладает правами собственности, не был отредактирован вручную и не несет ответственности за связанные с этим юридические вопросы. Если вы обнаружите материалы,涉嫌侵犯版权, пожалуйста, отправьте письмо по адресу: notice#oldtoolbag.com (во время отправки письма замените # на @), чтобы сообщить о нарушении, и предоставьте соответствующие доказательства. Если факт будет подтвержден, сайт немедленно удалил涉嫌侵权的内容.