If you think back to past interviews, you were often asked about transaction basics, transaction four attributes, isolation level, propagation behavior, @transcational principles, etc…. if you haven’t done microservices In daily CRUD business, adding, deleting, and modifying all involve transactions. Simple transaction handling is to add @transcational annotations to methods. This is not an elementary or novice consideration. In fact, @transcational is very important to add, delete and modify annotations. Based on reading so many blog posts and demos, I have tested and summarized relevant @transcational failure scenarios to share with you. In fact, these are the six scenarios that all the bloggers mentioned:

  • 1. Whether the database supports transactions

Some friends will ask, there is a database does not support transactions? I used to have this question, database has no transaction, that also make a hammer. Ha ha, naive idea let me suffer a lot of pain, after contact with big data, I know that there are many databases do not need transactions, of course, the mainstream database transactions are configurable, you do not want to, just do not configure, just shut down the bai. It’s a common development question when an interviewer asks you when transaction annotations expire. First of all, we should consider, whether the database opens the transaction, the database transaction related configuration support the current programming operation, such as mysql myIsam engine is not support transactions, there are some big data library, mostly not support transactions, such as the impala, you think about it, must level data model, and then put in storage , there is no need for business ah, because it has nothing to do with business increase or deletion.

  • 2. Whether the annotation class is managed by the Spring container, that is, whether it is a bean

@transcational annotations actually manage transactions in the agent mode. Think about it, who is the boss of the agent? Of course it is Spring, not dad’s son. For example, @service, @Configuration, @bean and other commonly used annotations are the concrete implementation of IOC. Only if you are dad’s big son, dad will take care of you

  • 3, call itself, single propagation behavior mutually exclusive

Make oneself also have no result, father also ignore, oneself play oneself, father also don’t know you need to tube. Here’s a copy of the code, for example: @Service public class OrderServiceImpl implements OrderService { @Transactional public void update(Order order) { updateOrder(order); } @Transactional(propagation = Propagation.REQUIRES_NEW) public void updateOrder(Order order) { // update order } } As you can see, the update method is annotated, but the transaction is configured by default. It calls the updateOrder method of the current class For the guidance of a transaction management agent at this time you don’t know who to listen to for the guidance of a transaction management agent ah: For the guidance of a transaction management agent what do you want?

  • 4. The modifier is not public

Spring’s transactions are AOP dynamically brokered and only apply to public-decorated methods, interfaces, and classes. Read the source code can see AbstractFallbackTransactionAttributeSource computeTransactionAttribute methods in this class

    protected TransactionAttribute computeTransactionAttribute(Method method, Class
        targetClass) { 
    // Don't allow no-public methods as required. 
    if(allowPublicMethodsOnly() && ! Modifier.isPublic(method.getModifiers())) {return null;
    }
Copy the code

As you can see, there is a determination of modifiers in this file. Anything that is not a public modifier cannot be proxy.

  • 5. The exception is caught

An exception rollback is specified, but the exception is caught when it occurs. When the exception is not thrown and the AOP proxy cannot get the exception, the exception rollback event will not be triggered. In the following example, the rollback exception is specified, but all exceptions occurring in the code block are caught, so the transaction rollback will not take effect

@Transactional(rollbackFor = Exception.class)
public void method(){
  try{
    insert();
    update();
  }catch(Exception ex){
    return; }}Copy the code

There are also some basic attributes related to @transcational annotations, which are actually transaction-related attributes, but some constants enumeration specifications are defined in Spring. The following supplementary information is copied from other places and posted here to share

isolation

  • The isolation level of the transaction, which is the defaultIsolation.DEFAULT.
  • The meanings of several values are as follows:
    • Isolation.DEFAULT: Transaction default isolation level, using the database default isolation level.
    • Isolation.READ_UNCOMMITTED: this is the lowest isolation level for a transaction and allows another transaction to see the uncommitted data of this transaction. This isolation level produces dirty reads, unrepeatable reads, and phantom reads.
    • Isolation.READ_COMMITTED: Ensures that data modified by one transaction is committed before it can be read by another transaction. Another transaction cannot read uncommitted data from that transaction. This transaction isolation level avoids dirty reads, but unrepeatable and phantom reads may occur.
    • Isolation.REPEATABLE_READ: This transaction isolation level prevents dirty, non-repeatable reads. But illusions can occur.
    • Isolation.SERIALIZABLE: This is the most expensive but reliable transaction isolation level. Transactions are processed for sequential execution. In addition to preventing dirty read, not repeat read, but also to avoid magic read.

propagation

  • Represents the propagation behavior of a transaction. The default value isPropagation.REQUIRED.
  • Propagation.REQUIRED: Supports the current transaction if one exists. If there are no transactions, start a new one. For example, if method A calls method B internally, method B will use method A’s transaction.
  • Propagation.MANDATORY: Supports the current transaction and throws an exception if there is no current transaction.
  • Propagation.NEVER: Executes nontransactionally and throws an exception if a transaction currently exists.
  • Propagation.NOT_SUPPORTED: Performs operations nontransactionally, suspending the current transaction if one exists.
  • Propagation.REQUIRES_NEW: Creates a transaction and suspends the current transaction if one exists. For example, method A uses the default transaction propagation property, and method B uses the default transaction propagation propertyREQUIRES_NEWIf method A is abnormal, the transaction in method A is rolled back, but method B is not rolled back. Because method A and method B use different transaction, method B creates A new transaction.
  • Propagation.NESTED: Supports current transactions. AddedSavepointPoint, that is, before entering the child transaction, the parent establishes a rollback point that is committed or rolled back synchronously with the current transaction. A child transaction is part of a parent transaction and must not have committed before the parent transaction has committed. A very important concept of nested transactions is that the inner transactions depend on the outer transactions. When an outer transaction fails, actions taken by the inner transaction are rolled back. The failure of the inner transaction does not cause the rollback of the outer transaction.

timeout

  • The timeout period for a transaction, in seconds.

readOnly

  • This property is used to set whether the current transaction is read-only, true means read-only, false means read/write, and the default is false. This can be set to true if a transaction is read-only only.

RollbackFor properties

  • Used to specify the type of exception that can trigger transaction rollback. Multiple exception types can be specified.
  • The default is inRuntimeExceptionandErrorRollback.

noRollbackFor

  • Throws the specified exception type, without rolling back the transaction, or you can specify multiple exception types.