** This is the third day of my participation in the August Gwen Challenge. For details, see: August Gwen Challenge **

While the first two chapters focus on handling data in SpringBoot, this chapter describes how to handle transactions. All data access technologies are dependent on transaction processing, otherwise data inconsistency will occur. Transaction is a series of actions, once there is an error in one of the actions, all must be rolled back, the system will be the transaction of all the completed operations on the database all undo, roll back to the state of the beginning of the transaction, to avoid the following series of errors caused by data inconsistency. The emergence of transaction is to ensure the integrity and consistency of data, in the current enterprise application development, transaction management is essential.

1. SpringBoot transaction mechanism

All transaction mechanisms provide apis to start transactions, commit transactions to complete data operations, or roll back data in case of errors to avoid data inconsistencies.

SpringBoot transaction mechanism is essentially the Spring transaction mechanism, is the mechanism that USES unified processing transactions from different data access technology, provides an interface PlatformTransactionManager, has can be different for different data access technology, in the following table.

Data access technology and implementation

Data access technology

The implementation class

JDBC

DataSourceTransactionManager

JPA

JpaTransactionManager

Hibernate

HibernateTransactionManager

JDO

JdoTransactionManager

Distributed transaction

JtaTransactionManager

The interface relationships are as follows:

Interface PlatformTransactionManager source code is as follows:

/*
 * Copyright 2002-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction;

import org.springframework.lang.Nullable;

/**
 * This is the central interface in Spring's transaction infrastructure.
 * Applications can use this directly, but it is not primarily meant as API:
 * Typically, applications will work with either TransactionTemplate or
 * declarative transaction demarcation through AOP.
 *
 * <p>For implementors, it is recommended to derive from the provided
 * {@link org.springframework.transaction.support.AbstractPlatformTransactionManager}
 * class, which pre-implements the defined propagation behavior and takes care
 * of transaction synchronization handling. Subclasses have to implement
 * template methods for specific states of the underlying transaction,
 * for example: begin, suspend, resume, commit.
 *
 * <p>The default implementations of this strategy interface are
 * {@link org.springframework.transaction.jta.JtaTransactionManager} and
 * {@link org.springframework.jdbc.datasource.DataSourceTransactionManager},
 * which can serve as an implementation guide for other transaction strategies.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @since 16.05.2003
 * @see org.springframework.transaction.support.TransactionTemplate
 * @see org.springframework.transaction.interceptor.TransactionInterceptor
 * @see org.springframework.transaction.interceptor.TransactionProxyFactoryBean
 */
public interface PlatformTransactionManager {

	/**
	 * Return a currently active transaction or create a new one, according to
	 * the specified propagation behavior.
	 * <p>Note that parameters like isolation level or timeout will only be applied
	 * to new transactions, and thus be ignored when participating in active ones.
	 * <p>Furthermore, not all transaction definition settings will be supported
	 * by every transaction manager: A proper transaction manager implementation
	 * should throw an exception when unsupported settings are encountered.
	 * <p>An exception to the above rule is the read-only flag, which should be
	 * ignored if no explicit read-only mode is supported. Essentially, the
	 * read-only flag is just a hint for potential optimization.
	 * @param definition TransactionDefinition instance (can be {@code null} for defaults),
	 * describing propagation behavior, isolation level, timeout etc.
	 * @return transaction status object representing the new or current transaction
	 * @throws TransactionException in case of lookup, creation, or system errors
	 * @throws IllegalTransactionStateException if the given transaction definition
	 * cannot be executed (for example, if a currently active transaction is in
	 * conflict with the specified propagation behavior)
	 * @see TransactionDefinition#getPropagationBehavior
	 * @see TransactionDefinition#getIsolationLevel
	 * @see TransactionDefinition#getTimeout
	 * @see TransactionDefinition#isReadOnly
	 */
	TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;

	/**
	 * Commit the given transaction, with regard to its status. If the transaction
	 * has been marked rollback-only programmatically, perform a rollback.
	 * <p>If the transaction wasn't a new one, omit the commit for proper
	 * participation in the surrounding transaction. If a previous transaction
	 * has been suspended to be able to create a new one, resume the previous
	 * transaction after committing the new one.
	 * <p>Note that when the commit call completes, no matter if normally or
	 * throwing an exception, the transaction must be fully completed and
	 * cleaned up. No rollback call should be expected in such a case.
	 * <p>If this method throws an exception other than a TransactionException,
	 * then some before-commit error caused the commit attempt to fail. For
	 * example, an O/R Mapping tool might have tried to flush changes to the
	 * database right before commit, with the resulting DataAccessException
	 * causing the transaction to fail. The original exception will be
	 * propagated to the caller of this commit method in such a case.
	 * @param status object returned by the {@code getTransaction} method
	 * @throws UnexpectedRollbackException in case of an unexpected rollback
	 * that the transaction coordinator initiated
	 * @throws HeuristicCompletionException in case of a transaction failure
	 * caused by a heuristic decision on the side of the transaction coordinator
	 * @throws TransactionSystemException in case of commit or system errors
	 * (typically caused by fundamental resource failures)
	 * @throws IllegalTransactionStateException if the given transaction
	 * is already completed (that is, committed or rolled back)
	 * @see TransactionStatus#setRollbackOnly
	 */
	void commit(TransactionStatus status) throws TransactionException;

	/**
	 * Perform a rollback of the given transaction.
	 * <p>If the transaction wasn't a new one, just set it rollback-only for proper
	 * participation in the surrounding transaction. If a previous transaction
	 * has been suspended to be able to create a new one, resume the previous
	 * transaction after rolling back the new one.
	 * <p><b>Do not call rollback on a transaction if commit threw an exception.</b>
	 * The transaction will already have been completed and cleaned up when commit
	 * returns, even in case of a commit exception. Consequently, a rollback call
	 * after commit failure will lead to an IllegalTransactionStateException.
	 * @param status object returned by the {@code getTransaction} method
	 * @throws TransactionSystemException in case of rollback or system errors
	 * (typically caused by fundamental resource failures)
	 * @throws IllegalTransactionStateException if the given transaction
	 * is already completed (that is, committed or rolled back)
	 */
	void rollback(TransactionStatus status) throws TransactionException;

}
Copy the code

Declarative transactions

Built on AOP, the essence is to intercept before and after a method, then create or join a transaction before the target method begins, and commit or roll back the transaction based on the execution of the target method after it has been executed. The biggest advantage of declarative transactions is that they do not need to be managed programmatically. This means that you do not need to mix transaction management code with your business logic code. Instead, you can apply transaction rules to your business logic by declaring them in a configuration file (or by using the @Transactional annotation).

Spring supports declarative transactions. When an annotated method is called, Spring starts a new transaction and commits the transaction when the method ends without exception.

Transactional public void insertUser(User User) {Transactional public void insertUser(User User) { }Copy the code

Note:

(1) @ Transactional from org. Springframework. Transaction. The annotation of package.

(2) @Transactional annotates not only methods but also classes. When an annotation is on a class, it means that all public methods of this class open a transaction. Using annotations at the class level overrides annotations at the method level if both class and method levels use the @Transactional annotation.

Here is the annotated @Transactional source:

(In order to reduce the number of articles, the annotation part was removed)

package org.springframework.transaction.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.core.annotation.AliasFor;
import org.springframework.transaction.TransactionDefinition;


@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {

	@AliasFor("transactionManager")
	String value() default "";
	
	@AliasFor("value")
	String transactionManager() default "";
	
	Propagation propagation() default Propagation.REQUIRED;

	Isolation isolation() default Isolation.DEFAULT;

	int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

	boolean readOnly() default false;

	Class<? extends Throwable>[] rollbackFor() default {};

	String[] rollbackForClassName() default {};
	
	Class<? extends Throwable>[] noRollbackFor() default {};

	String[] noRollbackForClassName() default {};
}
Copy the code

The following table describes the attributes:

attribute

type

describe

value

String

Optional qualified descriptor that specifies the transaction manager to use

propagation

enum: Propagation

Define the life cycle of a transaction, including REQUIRED, SUPPORTS, MANDATORY, REQUIRES_NEW, NOT_SUPPORTED, NEVER, and NESTED, Detailed meaning for enumeration class org. Springframework. Transaction. The annotation. The Propagation of source code.

isolation

enum: Isolation

The optional transaction isolation level setting determines the integrity of the transaction

readOnly

boolean

Read/write or read-only transactions, read/write by default

timeout

int (in seconds granularity)

Transaction timeout setting

rollbackFor

An array of Class objects that must inherit from Throwable

An array of exception classes that cause the transaction to roll back

rollbackForClassName

An array of class names that must be inherited from Throwable

Array of exception class names that cause the transaction to roll back

noRollbackFor

An array of Class objects that must inherit from Throwable

An array of exception classes that do not cause the transaction to roll back

noRollbackForClassName

An array of class names that must be inherited from Throwable

An array of exception class names that will not cause the transaction to roll back

In SpringBoot, it is recommended to use the @Transactional annotation for transaction control.