Транзакции, поддерживаемые Spring
Spring предоставляет два метода управления транзакциями: программный и декларативный.
-
编程式
: Включение, фиксация или откат транзакций вручную с помощью кодирования с более тонкой детализацией, но с большими проблемами. -
声明式
: Обтекание путем добавления аннотаций к методам или классам или интерфейсам для реализации транзакций без навязчивости, что более удобно, но с большей степенью детализации.
Важно отметить, что используемая база данных должна поддерживать транзакции, иначе транзакции не будут работать. Например, механизм MyIsam MySql не поддерживает транзакции.
Конфигурация транзакций Spring
добавить зависимости
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
Настройка диспетчера транзакций
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 如果使用基于注解的声明式事务,需要配置annotation-driven -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
Очевидно, что dataSource у transactionManager должен быть dataSource операции транзакции в коде, иначе как им управлять.
Использование алгоритмических транзакций
Запустите, зафиксируйте или откатите транзакцию в коде:
// 开始事务
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
// 异常回滚,并不一定要在try...catch中
transactionManager.rollback(status);
// 提交事务
transactionManager.commit(status);
Как правило, подходящий метод использования:
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
// 进行需要处在同一事务中的数据库操作
......
// 正常结束,提交事务
transactionManager.commit(status);
} catch (SomeException) {
// 错误处理
......
// 回滚
transactionManager.rollback(status);
}
Использование декларативных транзакций
Добавить непосредственно в класс или в метод@Transaction
Просто аннотируйте:
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
public int save(Info info) throws Exception {
@Transaction
Общие параметры аннотаций:
поведение распространения
-
REQUIRED(默认值)
Должен выполняться в контексте с транзакцией: если текущей (внешней) транзакции нет, создается новая транзакция, если есть существующая (внешняя) транзакция, она добавляется к текущей (внешней) транзакции. (Если вызываемый метод выдает исключение, и вызывающий метод, и транзакция вызываемого метода будут отброшены.) Это наиболее распространенный выбор. -
SUPPORTS
Поддерживается текущая (внешняя) транзакция, и если текущая (внешняя) транзакция отсутствует, она выполняется нетранзакционным образом. -
MANDATORY
Заставляет использовать текущую (внешнюю) транзакцию или создает исключение, если текущей (внешней) транзакции нет. -
REQUIRES_NEW
Создайте новую транзакцию и запустите ее в транзакции. Если есть текущая (внешняя) транзакция, сначала приостановите текущую (внешнюю) транзакцию. -
NOT_SUPPORTED
Выполнить операцию без транзакций: приостановить текущую (внешнюю) транзакцию, если есть текущая (внешняя) транзакция. -
NEVER
Выполнить нетранзакционно: выдает исключение, если в данный момент существует (внешняя) транзакция. -
NESTED
Выполнение вложенным образом: если есть текущая (внешняя) транзакция, она будет выполняться независимо в своей собственной транзакции вложенным образом, не затрагивая текущую (внешнюю) транзакцию, и если текущая (внешняя) транзакция откатывается, Транзакция также должна быть отброшена, если (внешняя) транзакция в настоящее время не существует, выполняется операция, аналогичная PROPAGATION.REQUIRED.
уровень изоляции
-
DEFAULT
Использовать уровень изоляции транзакций базы данных по умолчанию -
READ_UNCOMMITTED
Разрешает чтение незафиксированных изменений, что может привести к грязному чтению, фантомному чтению и неповторяемому чтению. -
READ_COMMITTED
Разрешает чтение из зафиксированных транзакций, чтобы предотвратить грязное чтение, но фантомное чтение и неповторяемое чтение по-прежнему возможно. -
REPEATABLE_READ
Результаты многократного чтения одного и того же поля непротиворечивы, если данные не изменены самой текущей транзакцией. Грязные чтения и неповторяющиеся чтения можно предотвратить, но фантомные чтения все еще могут возникать. -
SERIALIZABLE
Полностью соблюдайте принцип изоляции ACID, чтобы гарантировать, что грязные чтения, неповторяемые чтения и фантомные чтения не происходят, но эффективность выполнения будет самой низкой.
readOnly — транзакция только для чтения
Указывает, читает ли транзакция только данные, но не обновляет данные. Установка для транзакции только для чтения значения только для чтения может помочь ядру базы данных оптимизировать транзакцию.
тайм-аут тайм-аут
Избегайте блокировки базы данных на долгое время, в секундах.
rollbackДля класса исключений отката
По умолчанию откатываются только исключения времени выполнения, см. ниже.
Подводные камни декларативных транзакций
внутренний вызов класса
Декларативная транзакция Spring динамически проксируется через АОП, поэтому будет создан класс, реализующий прокси транзакции, который отличается от исходного класса. Рассмотрим ситуацию:
- Метод A в классе обслуживания не объявляет транзакцию
- Метод B в службе объявляет транзакцию
- Метод A вызывает метод B внутри
В это время вызывается метод B службы, и используется метод B прокси-класса Service', который реализует метод транзакции и будет откатываться при возникновении исключения.
Однако если вызывается метод A, а внутри прокси-класса используется метод B исходного класса Service, а транзакция не реализована, это вызовет аварийный откат.
Решение: разбить метод B на другие классы и обернуть его транзакцией, чтобы гарантировать вызов метода прокси-класса вместо исходного класса.
Неправильное использование
Декларативный метод с оболочкой транзакции будет выполнять откат, когда метод выдает исключение, но по умолчанию он выдает только исключение.RuntimeException
откат.
Если исключение проглочено уловом или не-RuntimeException
, то по умолчанию откат не выполняется.
Решение: не проглатывать исключения, сталкиваться с не-RuntimeException
,использовать@Transaction
аннотированныйrollbackFor
параметры контролируются.
Частичная иерархия классов java.lang в Java8 выглядит следующим образом (полную структуру см. в ссылках внизу статьи):
java.lang.Object
......
java.lang.Throwable (implements java.io.Serializable)
java.lang.Error
java.lang.AssertionError
java.lang.LinkageError
java.lang.BootstrapMethodError
java.lang.ClassCircularityError
java.lang.ClassFormatError
java.lang.UnsupportedClassVersionError
java.lang.ExceptionInInitializerError
java.lang.IncompatibleClassChangeError
java.lang.AbstractMethodError
java.lang.IllegalAccessError
java.lang.InstantiationError
java.lang.NoSuchFieldError
java.lang.NoSuchMethodError
java.lang.NoClassDefFoundError
java.lang.UnsatisfiedLinkError
java.lang.VerifyError
java.lang.ThreadDeath
java.lang.VirtualMachineError
java.lang.InternalError
java.lang.OutOfMemoryError
java.lang.StackOverflowError
java.lang.UnknownError
java.lang.Exception
java.lang.CloneNotSupportedException
java.lang.InterruptedException
java.lang.ReflectiveOperationException
java.lang.ClassNotFoundException
java.lang.IllegalAccessException
java.lang.InstantiationException
java.lang.NoSuchFieldException
java.lang.NoSuchMethodException
// 这里是RuntimeException
java.lang.RuntimeException
java.lang.ArithmeticException
java.lang.ArrayStoreException
java.lang.ClassCastException
java.lang.EnumConstantNotPresentException
java.lang.IllegalArgumentException
java.lang.IllegalThreadStateException
java.lang.NumberFormatException
java.lang.IllegalMonitorStateException
java.lang.IllegalStateException
java.lang.IndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.StringIndexOutOfBoundsException
java.lang.NegativeArraySizeException
java.lang.NullPointerException
java.lang.SecurityException
java.lang.TypeNotPresentException
java.lang.UnsupportedOperationException
......
использованная литература
Декларативные транзакции Spring — краткая книга
Spring Declarative Transaction Ошибка транзакции вызова метода в том же классе
java.lang Class Hierarchy (Java Platform SE 8 )
Переход от бумагимой блог, добро пожаловать в гости!