Обзор
Управление транзакциями имеет решающее значение для корпоративных приложений, которые могут обеспечить согласованность данных даже в нештатных ситуациях. Spring Framework предоставляет согласованную абстракцию для управления транзакциями со следующими характеристиками:
- Обеспечить согласованную модель программирования для различных API транзакций, таких как JTA (API транзакций Java), JDBC, Hibernate, JPA (API сохранения состояния Java и JDO (объекты данных Java)).
- Поддержка декларативного управления транзакциями, особенно декларативное управление транзакциями на основе аннотаций, простое в использовании.
- Предоставляет более простой программный API управления транзакциями, чем другие API транзакций, такие как JTA.
- Идеальная интеграция с абстракцией доступа к данным spring
управление бизнесом
Spring поддерживает как программное управление транзакциями, так и декларативное управление транзакциями.
Программное управление транзакциями с помощью TransactionTemplate или непосредственно с помощью базового PlatformTransactionManager. Для программного управления транзакциями Spring рекомендует использовать TransactionTemplate.
Декларативное управление транзакциями построено на основе АОП. Его суть заключается в том, чтобы перехватить метод до и после, а затем создать или присоединиться к транзакции до запуска целевого метода и зафиксировать или откатить транзакцию в соответствии со статусом выполнения после выполнения целевого метода. Самое большое преимущество декларативных транзакций заключается в том, что нет необходимости программно управлять транзакциями, поэтому нет необходимости смешивать код управления транзакциями с кодом бизнес-логики, просто сделайте соответствующие объявления правил транзакций в файлах конфигурации (или с помощью метода @Transactional Annotation), вы можете применять правила транзакций к бизнес-логике.
Очевидно, что декларативное управление транзакциями лучше, чем программное управление транзакциями, которое является ненавязчивым методом разработки, за который выступает Spring. Декларативное управление транзакциями защищает бизнес-код от загрязнения.Обычный объект POJO может получить полную поддержку транзакций, если он аннотирован. По сравнению с программными транзакциями единственным недостатком декларативных транзакций является то, что более тонкая детализация последних может применяться только к уровню метода и не может применяться к уровню блока кода, как программные транзакции. Но даже если есть такой спрос, есть много обходных путей, например, блок кода, который нуждается в управлении транзакциями, может быть независимым как метод и так далее.
Существует также два распространенных способа декларативного управления транзакциями: один основан на файле конфигурации xml пространств имен tx и aop, а другой основан на аннотации @Transactional. Очевидно, что метод на основе аннотаций проще в использовании и чище.
Следует ли AutoCommit и следует ли автоматически фиксировать при закрытии соединения
автоматическая фиксация
По умолчанию база данных находится в режиме автоматической фиксации. Каждый оператор находится в отдельной транзакции.Когда оператор выполняется, транзакция неявно фиксируется, если выполнение успешно, и транзакция неявно откатывается, если выполнение завершается ошибкой.
Для нормального управления транзакциями в транзакции находится группа связанных операций, поэтому режим автофиксации базы данных должен быть выключен. Однако нам не нужно об этом беспокоиться, Spring установит для функции автоматической фиксации базового соединения значение false.
org/springframework/jdbc/datasource/DataSourceTransactionManager.java
// switch to manual commit if necessary. this is very expensive in some jdbc drivers,
// so we don't want to do it unnecessarily (for example if we've explicitly
// configured the connection pool to set it already).
if (con.getautocommit()) {
txobject.setmustrestoreautocommit(true);
if (logger.isdebugenabled()) {
logger.debug("switching jdbc connection [" + con + "] to manual commit");
}
con.setautocommit(false);
}
Конфигурация декларативного управления транзакциями на основе аннотаций
applicationContext.xml
<!-- 事务:第一步,配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入属性dataSource,表明事务管理器要对哪个数据源进行管理 -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--事务注解方式: 第二步,开启事务注解 【在需要事务管理的方法上加上@Transactional注解即可】-->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
до сих пор внутриapplicationContext.xml
добавлено вtx
пространство имен
...
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
...
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
...
MyBatis автоматически участвует в управлении транзакциями spring без дополнительной настройки, еслиorg.mybatis.spring.SqlSessionFactoryBean
Ссылочный источник данных такой же, какDataSourceTransactionManager
Ссылочный источник данных должен быть непротиворечивым, иначе управление транзакциями работать не будет.
особенности весенней транзакции
1. Уровень изоляции транзакции
Уровень изоляции относится к степени изоляции между несколькими одновременными транзакциями. В интерфейсе TransactionDefinition определены пять констант, представляющих уровни изоляции:
-
TransactionDefinition.ISOLATION_DEFAULT:Это значение по умолчанию, что означает использование уровня изоляции базовой базы данных по умолчанию. Для большинства баз данных это обычно TransactionDefinition.ISOLATION_READ_COMMITTED.
-
TransactionDefinition.ISOLATION_READ_UNCOMMITTED: этот уровень изоляции указывает, что транзакция может считывать данные, измененные другой транзакцией, но еще не зафиксированные. Этот уровень не предотвращает грязные чтения, неповторяемые чтения и фантомные чтения, поэтому этот уровень изоляции используется редко. Например, PostgreSQL на самом деле не имеет этого уровня.
-
TransactionDefinition.ISOLATION_READ_COMMITTED: этот уровень изоляции означает, что транзакция может считывать только те данные, которые были зафиксированы другой транзакцией. Этот уровень предотвращает грязное чтение и является рекомендуемым значением в большинстве случаев.
-
TransactionDefinition.ISOLATION_REPEATABLE_READ: этот уровень изоляции указывает, что транзакция может повторять запрос несколько раз в течение всего процесса, и каждый раз возвращаются одни и те же записи. Этот уровень предотвращает грязные чтения и неповторяющиеся чтения.
-
TransactionDefinition.ISOLATION_SERIALIZABLE: Все транзакции выполняются одна за другой, так что абсолютно исключена возможность интерференции между транзакциями, то есть этот уровень может предотвращать грязные чтения, неповторяемые чтения и фантомные чтения. Но это серьезно повлияет на производительность программы. Обычно этот уровень также не используется.
2. Поведение при распространении транзакций
Так называемое поведение распространения транзакций означает, что если контекст транзакции уже существует до запуска текущей транзакции, существует несколько вариантов для указания поведения выполнения транзакционного метода. Следующие константы, представляющие поведение распространения, включены в определение TransactionDefinition:
-
TransactionDefinition.PROPAGATION_REQUIRED: если транзакция уже существует, присоединиться к транзакции, если текущей транзакции нет, создать новую транзакцию.Это значение по умолчанию.
-
TransactionDefinition.PROPAGATION_REQUIRES_NEW: создать новую транзакцию, если есть текущая транзакция, приостановить текущую транзакцию.
-
TransactionDefinition.PROPAGATION_SUPPORTS: если в данный момент есть транзакция, присоединиться к транзакции, если текущей транзакции нет, продолжить выполнение в нетранзакционном режиме.
-
TransactionDefinition.PROPAGATION_NOT_SUPPORTED: запустить в нетранзакционном режиме, если есть текущая транзакция, приостановить текущую транзакцию.
-
TransactionDefinition.PROPAGATION_NEVER: работает в нетранзакционном режиме и создает исключение, если транзакция уже существует.
-
TransactionDefinition.PROPAGATION_MANDATORY: если в данный момент есть транзакция, присоединиться к транзакции, если текущей транзакции нет, создать исключение.
-
TransactionDefinition.PROPAGATION_NESTED: если транзакция в настоящее время существует, создайте транзакцию для запуска в качестве вложенной транзакции текущей транзакции; если текущей транзакции нет, значение эквивалентно TransactionDefinition.PROPAGATION_REQUIRED.
3. Тайм-аут транзакции
Так называемый тайм-аут транзакции относится к максимальному времени, разрешенному для выполнения транзакции.Если лимит времени превышен, но транзакция не была завершена, транзакция будет автоматически отменена. В TransactionDefinition тайм-аут представлен значением int, единицей измерения которого являются секунды.
Значением по умолчанию является значение тайм-аута базовой системы транзакций.Если базовая система транзакций базы данных не устанавливает значение тайм-аута, то оно равно нулю и предела тайм-аута нет.
весенние правила отката транзакций
Spring использует декларативную обработку транзакций,по умолчанию, если в методе операции с аннотированной базой данных возникает непроверенное исключение, все операции с базой данных будут откатываться; если возникшее исключение является проверенным исключением, операция базы данных все равно будет отправлена по умолчанию.
проверенное исключение (Exception):
Указывает недопустимое, не предсказуемое в программе. Например, неверный пользовательский ввод, файл не существует, ошибка сети или связи с базой данных. Это все внешние причины, и ни одну из них нельзя контролировать внутри программы. Должен обрабатываться явно в коде. Например, блок обработки try-catch или добавить описание бросков к методу, где он находится, и бросить исключение на верхний уровень стека вызовов. Унаследовано от java.lang.Exception (кроме java.lang.RuntimeException).
Непроверенное исключение (RuntimeException):
Указывает на ошибку, логическую ошибку в программе. Является подклассом RuntimeException, например IllegalArgumentException, NullPointerException и IllegalStateException. Нет необходимости явно перехватывать непроверенные исключения в вашем коде для обработки. Унаследовано от java.lang.RuntimeException
(в то время как java.lang.RuntimeException наследуется от java.lang.Exception)
Примечание: по умолчанию Spring откатывает транзакцию для непроверенных (RunTimeException, Error) исключений, но не для проверенных (Exception) исключений.
Как сделать проверенное исключение еще и откатным? Например, настройка @Transactional(rollbackFor= Exception.class) Exception является родительским классом RunTimeException, такая конфигурация включает в себя (checked и unchecked), эта конфигурация рекомендуется в проекте
@Транзакционная аннотация
Уведомление
@Transactional можно применять к интерфейсам, методам интерфейса, классам и методам классов. При использовании в классе все общедоступные методы класса будут иметь атрибуты транзакций этого типа, и мы также можем использовать эту аннотацию на уровне метода, чтобы переопределить определение уровня класса.
Хотя аннотация @Transactional может действовать на интерфейсы, методы интерфейса, классы и методы классов,Spring не рекомендует использовать эту аннотацию в интерфейсах или методах интерфейса., так как это вступит в силу только при использовании прокси на основе интерфейса. Кроме того,Аннотацию @Transactional следует применять только к общедоступным методам., что определяется характером Spring AOP. Если вы аннотируете метод с защищенной, частной или видимостью по умолчанию с помощью @Transactional, это будет проигнорировано, и исключение не будет выдано.
По умолчанию прокси-сервер AOP перехватывает только вызовы методов извне., то есть метод внутри класса, который вызывает другие методы внутри этого класса, не будет вызывать транзакционного поведения, даже если вызываемый метод украшен аннотацией @Transactional.
Ссылаться на:Блог Woohoo.cn на.com/people bullying/fear/… blog.CSDN.net/U013142781/…