Eight reasons why Spring transactions take effect

This is a question asked by the interviewer in the previous interview. I didn't answer it very well, so I'll summarize it here (my summary may be lacking, but the interview is enough)
1. The database engine does not support transactions
Let's take MySQL as an example. MyISAM engine does not support transaction operations. InnoDB is the engine that supports transactions. In general, InnoDB will be used to support transactions.
2. Not managed by Spring
For example, the following code:

// @Service
public class OrderServiceImpl implements OrderService {
    @Transactional
    public void updateOrder(Order order) {
        // update order
    }
}

If the @ Service annotation is commented out at this time, this class will not be loaded into a Bean, and this class will not be managed by Spring, and the transaction will naturally become invalid.
3. Is the method where the annotation is located modified by public
That is, @ Transactional can only be used on public methods, otherwise transactions will fail. If you want to use it on non-public methods, you can turn on AspectJ proxy mode
4. Self call problem
For example, the following code: it doesn't work

Our update method is not annotated with @ Transactional annotation. Call the updateOrder method with @ Transactional annotation. Do you think the transactions on the updateOrder method work?

@Service
public class OrderServiceImpl implements OrderService {
    public void update(Order order) {
        updateOrder(order);
    }
    @Transactional
    public void updateOrder(Order order) {
        // update order
    }   
}

Looking at the following code, we added @ Transactional to the update method and requirements to the updateOrder_ New starts a new transaction. Does the new transaction work?
**Reason: * * because they call themselves, they call their own methods of the class without passing through the proxy class of Spring. By default, transactions will take effect only when they are called externally. This is also an old classic problem.
One of the solutions to this problem is to inject yourself into your class and call another method with the injected object. This is not very elegant. Another feasible solution can be referred to https://mp.weixin.qq.com/s/1TEBnmWynN4nwc6Q-oZfvw This article
5. The data source does not have a transaction manager configured
If the transaction manager is not configured for the current data source, the transaction will also take effect
6. Transaction not supported
As shown in the following code:

@Service
public class OrderServiceImpl implements OrderService {
    @Transactional
    public void update(Order order) {
        updateOrder(order);
    }
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void updateOrder(Order order) {
        // update order
    }
}

Propagation.NOT_SUPPORTED: indicates that it does not run as a transaction. If there is a transaction, it will be suspended,
If you don't support running in transaction mode, it's useless for the transaction to take effect!
7. Abnormal was eaten
For example:

// @Service
public class OrderServiceImpl implements OrderService {

    @Transactional
    public void updateOrder(Order order) {
        try {
            // update order
        } catch {
            
        }
    }
    
}

Eat the exception and then don't throw it out. How do you roll back the transaction? Ha ha
8. Exception type error
If the above example throws another exception:

// @Service
public class OrderServiceImpl implements OrderService {

    @Transactional
    public void updateOrder(Order order) {
        try {
            // update order
        } catch {
            throw new Exception("Update error");
        }
    }
    
}

In this way, the transaction will not take effect, because the default rollback is RuntimeException. If you want to trigger the rollback of other exceptions, you need to configure it on the annotation
For example: @ Transactional(rollbackFor = Exception.class)
summary
This paper summarizes eight scenarios of transaction failure. In fact, the most common scenarios are self invocation, exception being eaten, and wrong exception throwing type.
This article does not necessarily summarize the whole, but only summarizes the common scenarios of transaction failure. Even so, these 8 points are enough to help you hang the interviewer

Tags: Java Spring Back-end

Posted on Sun, 28 Nov 2021 13:20:59 -0500 by mesz