The transaction is introduced

concept

In a relational database, a transaction can be a SINGLE SQL statement, a set of SQL statements, or an entire program.

Transactions are the basic unit of recovery and concurrency control.

ACID

Transactions should have four attributes: atomicity, consistency, isolation, and persistence. These four properties are commonly referred to as ACID properties.

Atomicity. A transaction is an indivisible unit of work in which all or none of the operations involved are performed.

Consistency. Transactions must change the database from one consistent state to another. Consistency is closely related to atomicity.

Isolation. The execution of a transaction cannot be interfered with by other transactions. That is, the operations and data used within a transaction are isolated from other concurrent transactions, and the concurrent transactions cannot interfere with each other.

They are persistent. Persistence, also known as permanence, means that once a transaction is committed, its changes to the data in the database should be permanent. Subsequent operations or failures should not affect it in any way.

Concurrency issues for transactions

1. Dirty reads

Transaction A reads the data updated by transaction B, and then B rolls back the operation, so the data A reads is dirty.

2. It cannot be read repeatedly

Transaction A reads the same data for many times, and transaction B updates and commits the data during the process of reading the same data for many times. As A result, when transaction A reads the same data for many times, the results are inconsistent.

3. The magic to read

System administrator A changed the score of all the students in the database from the specific score to ABCDE level, but system administrator B inserted A specific score record at this time. When system administrator A finished the change, it found that there was still A record that had not been changed, as if there was an illusion, which is called phantom reading.

Transaction isolation level

1. Read uncommitted

If one transaction has already started writing data, another transaction is not allowed to write simultaneously, but other transactions are allowed to read this row. This isolation level can be achieved through an “exclusive write lock” that does not exclude reading threads. This avoids update loss, but may result in dirty reads, which means that transaction B reads data that transaction A has not committed.

Updates are missing, but dirty reads are still possible

2. Read Committed

If it is a read transaction (thread), other transactions are allowed to read and write. If it is a write transaction, other transactions are prevented from accessing the data in the row. This isolation level avoids dirty reads, but unrepeatable reads may occur. Transaction A reads the data first, transaction B then updates the data and commits the transaction, and when transaction A reads the data again, the data has changed.

Updates lost and dirty reads are resolved

Repeatable read(Repeatable read)

Repeatable read is to point to in a transaction, read the same data for many times, at the end of this transaction has not, other transactions cannot access the data (including the reading and writing), so you can read for the second time in the same transaction data is the same, so called is repeatable read isolation level, read data transaction will prohibit write transactions (but allow read transactions), Write transactions prohibit any other transactions (including reads and writes), which avoids unrepeatable and dirty reads, although phantom reads can sometimes occur. This can be done with shared read mirrors and exclusive write locks.

Solved update loss, dirty read, unrepeatable read, but there will be unreal read

4. Serializable

Provides strict transaction isolation, which requires that transactions be serialized and executed one after another, but not concurrently. Serialization cannot be achieved by “row-level locking” alone, and other mechanisms must be used to ensure that newly inserted data is not accessed by transactions performing query operations. Serialization is the highest transaction isolation level, but also the most expensive. It has low performance and is rarely used. At this level, transactions are executed sequentially to avoid dirty reads, non-repeatable reads, and phantom reads

Fix update loss, dirty read, unrepeatable read, phantom read (virtual read)

5. Default(Default isolation level)

Most databases such as Oracle are RC.

The isolation level of Mysql is RR by default.

@ Transational parsing

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
    @ AliasFor (" transactionManager ")
    String value(a) default"";

    @ AliasFor (" value ")
    String transactionManager(a) default"";

    Propagation propagation(a) default Propagation.*REQUIRED*;

    Isolation isolation(a) default Isolation.*DEFAULT*;

    int timeout(a) default- 1;

    boolean readOnly(a) default false;

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

    String[] rollbackForClassName() default {};

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

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

Target

The @Transactional annotation can also be added at the class level, or at the method level. When the @Transactional annotation is placed at the class level, it means that all public methods of the class are configured with the same transaction attribute information. When @Transactional is configured at the class level and @Transactional is configured at the method level, the application manages transactions with method-level transaction attribute information that overrode the class-level configuration information.

Propagation

  • PROPAGATION_REQUIRED

If there is no transaction, create a new one. If there is already one, join it. This is the most common choice.

  • PROPAGATION_SUPPORTS

Current transactions are supported, and non-transactionally executed if there are none.

  • PROPAGATION_MANDATORY

Use the current transaction and throw an exception if there is no transaction currently.

  • PROPAGATION_REQUIRES_NEW

Create a new transaction and suspend the current transaction if one exists.

  • PROPAGATION_NOT_SUPPORTED

Performs the operation nontransactionally, suspending the current transaction if one exists.

  • PROPAGATION_NEVER

Executes nontransactionally, throwing an exception if a transaction currently exists.

  • PROPAGATION_NESTED

If a transaction currently exists, it is executed within a nested transaction. If there are no transactions currently, an operation similar to PROPAGATION_REQUIRED is performed.

Isolation

DEFAULT(-1),
READ_UNCOMMITTED(1),
READ_COMMITTED(2),
REPEATABLE_READ(4),
SERIALIZABLE(8);
Copy the code

Details are the same as isolation levels.

readOnly

Set the transaction’s read-only property, which, if set to true, automatically provides a means of optimization.

Rollback

  • rollbackFor

An array of Class objects that must inherit from an array of exception classes that Throwable causes the transaction to roll back

  • rollbackForClassName

An array of class names that must inherit from the array of exception class names that Throwable causes the transaction to roll back

  • noRollbackFor

An array of Class objects that must inherit from an array of Throwable exception classes that do not cause a transaction rollback

  • noRollbackForClassName

An array of class names that must inherit from an array of exception class names that Throwable does not cause a transaction to roll back

If the rollbackFor attribute is not configured in the @Transactional annotation, transaction rollback occurs only when uncontrolled exceptions (RuntimeException and Error) occur.

Transactional(rollbackFor= exception.class). If a class annotates this annotation, methods within that class throw exceptions that are rolled back.

Similarly, after noRollback is configured, you can specify that special exceptions are not rolled back.

@Transactional is a common scenario that doesn’t work

  1. The modifier method is not Public.

  2. Class calls that call the @Transactional annotation within a class.

  3. The transaction method catches the exception internally, and no new exception is thrown, resulting in the transaction operation not being rolled back.

  4. Methods decorated with @transactional call @async internally, so that they are not in the same thread.