Spring transaction in the actual project development

First, some basics brief review of the transaction, not talking about very deeply, many online blog.

   1, on the four transaction properties of: Atomicity, isolation, consistency, persistence omitted herein;

   2, isolation level of the transaction: read uncommitted, read committed, repeatable read, serialization (here should understand what problems occur at all levels, such as dirty reads, non-repeatable read, phantom read)

   3, the propagation of transaction: transaction propagation behavior refers to a transaction when the transaction method calls another method, this method should be how to make the transaction. For example: methodA transaction method is invoked methodB transaction method, methodB is to continue to run the affairs of the caller methodA it, or start a new run their own affairs, which is determined by the propagation behavior methodB transactions. Defaults: PROPAGATION_REQUIRED

Second, let's briefly review the Java exception hierarchy:

Throwable is the Java language in all the wrong or unusual superclass in Java only instance of type Throwable can be thrown (throw) or capture (catch), which is the basic type of exception handling mechanism.
Examples of Error and Exception divided into two kinds.

Error category refers to internal errors and resource depletion system java runtime error. Applications will not throw objects in that class. If
such an error occurs, in addition to informing the user, and the rest is try to make the program safe termination.

Exception there are two branches, one is RuntimeException abnormal operation, a check is abnormal CheckedException.

RuntimeException such as: a NullPointerException, a ClassCastException;
CheckedException as: IOException I / O errors due to, SQLException.

RuntimeException is the superclass of those exceptions that might be thrown during the normal operation of the Java Virtual Machine. If RuntimeException occurs, then a
given error is caused by the programmer to write code.

CheckedException: General external error, such anomalies occur at compile time, Java compiler strong
system program to catch such exceptions, will appear asking you to put this program may be abnormal try catch

Third, the use Closer to home, the project Affairs

 springboot configured to automatically configure the default transaction manager for us, we refer to another article https://www.cnblogs.com/enchaolee/p/11364025.html

We in the actual development of the project, for the transaction of business, nothing less use in coding @Transactional this annotation, as well as for handling exceptions, let's talk about in detail.

1, after adding @Transactional comment on the method, which has become a transactional method, if no special configuration for some properties annotation, then the method if there is a RuntimeException (abnormal operation), the transaction will be rolled back, if there is the checkedException (abnormal compile time), it will not be rolled back. So for such exceptions, we want him to be rolled back how to do it when thrown, when we point into @Transactional comments, see figure below:

We can see, there are two figures marked red properties of the annotation, we can here be manually configured to implement the specific method throws exception rollback logic. For example, we can be configured: @Transactional (rollbackFor = Exception.class);

Of course, there are two fields can be set not throw an exception to roll back certain: noRollbackFor, noRollbackForClassName;

2, for the exception caught, how to deal with affairs

If we in the transaction process, manually capture the exception and did not let matters go throw, there is no need to manually specify the rollback, the transaction method, even if an exception occurs, will commit the transaction.

For example, we do so, just log records, even if rollbackfor = Exception.class developed a logic needs to be rolled back, but the transaction will still be submitted, unless insert the following line:

This code does not need to have abnormalities, but this is not recommended when thrown manually run because this code will be a lot more transaction rollback code, is not conducive to the maintenance, or have to pay more spring to deal with properly. 3, the

 3, we like how to handle exceptions rollback it?

As shown, CommonException is a global exception classes we define, we can catch the exception thrown unified according to a certain format. Here is the relevant code CommonException

public class CommonException extends RuntimeException {

    protected String errMsg; // error message is displayed to the user
    protected String detailMsg; // error specific information may contain information other parameters ID
    protected CommonErrorCode error; // error code
    protected Object data; // return the content

    public CommonException(CommonErrorCode error) {
        super(error.getDesc());
        this.error = error;
        this.errMsg = error.getDesc();
        this.detailMsg = error.getDesc();
    }

    public CommonException(CommonErrorCode error, String errMsg) {
        super(errMsg);
        this.error = error;
        this.errMsg = errMsg;
        this.detailMsg = errMsg;
    }

    public CommonException(CommonErrorCode error, String errMsg, String detailMsg) {
        super(StringUtils.isEmpty(detailMsg) ? errMsg : detailMsg);
        this.error = error;
        this.errMsg = errMsg;
        this.detailMsg = detailMsg;
    }

    public CommonException(CommonErrorCode error, String errMsg, Throwable cause) {
        super(errMsg, cause);
        this.error = error;
        this.errMsg = errMsg;
        this.detailMsg = errMsg;
    }

    public CommonException(CommonErrorCode error, String errMsg, String detailMsg, Throwable cause) {
        super(StringUtils.isEmpty(detailMsg) ? errMsg : detailMsg, cause);
        this.error = error;
        this.errMsg = errMsg;
        this.detailMsg = detailMsg;
    }

    public CommonException(CommonErrorCode error, Throwable cause) {
        super(error.getDesc(), cause);
        this.error = error;
        this.errMsg = error.getDesc();
        this.detailMsg = error.getDesc();
    }

    public String getErrMsg() {
        return errMsg;
    }

    public CommonErrorCode getError() {
        return error;
    }

    public String getDetailMsg() {
        return detailMsg;
    }

    public void setDetailMsg(String detailMsg) {
        this.detailMsg = detailMsg;
    }

    public void setErrMsg(String errMsg) {
        this.errMsg = errMsg;
    }

    public Object getData() {
        return data;
    }

    public CommonException setData(Object data) {
        this.data = data;
        return this;
    }
}

4, transaction method transaction method calls, how to deal with

First we confirm a premise: the propagation of transaction we use the default namely: required, and we assume that there are two transactions method a, b; a call b.

(1) according to the characteristics required of the above we have said, we know that spring for calls between this transaction method, as it will default to a transaction; if we assume b thrown in NullpointException, and a, b are not doing exception handling, the entire transaction by the a, b composed certainly will be rolled back, it is beyond doubt.

(2) If b is abnormal, a catch the exception, and not thrown to, as we say in the above example only log record, we find that this exception, think about why?

    We know that spring transaction management, enable transaction method, when calling another transaction method, the transaction will be spread. Notes @Transactional default propagation mechanism is PROPAGATION_REQUIRED. Again look required characteristics: The current method must run within a transaction. If the current transaction exists, the method will run in that transaction. Otherwise, it will start a new transaction

    So it's time to run the padded method, simultaneous merger transaction to transaction inside padded. When the invoice abnormal synchronization occurs, try catch is captured, not thrown out. But still rollback transaction rollback to perform the method doSetRollbackOnly DataSourceTransactionManager class, provided rollbackOnly = true;

Since the exception is catch, it does not block the entire transaction execution. After the implementation of the entire transaction, a commit to submit, we open this abstract class AbstractPlatformTransactionManager look at the logic commit

Here I marked red this approach, we continue to look down, we open DefaultTransactionStatus this class, you can see the red mark specific implementation method.

Commit the logic when executed, performing a method to isGlobalRollbackOnly DefaultTransactionStatus class rollbackOnly determination is true, the roll back log and the play given phrase "Transaction rolled back because it has been marked as rollback-only".

5, need to pay attention to some points

  (1) The method requires the transaction marked as public

  (2) @Transactional annotation can only write in service, the controller is no longer in, otherwise it will report a 404 error 

  (3) If in the case of a transaction, all operations are read operations, it recommended that the transaction is set to read-only transaction, when the transaction is marked as read-only transaction, Spring can be optimized for read-only transactions for certain the resources can perform the appropriate optimization measures need to manually set to true. But then perform CRUD method back to throw an exception.

Guess you like

Origin www.linuxidc.com/Linux/2019-08/160247.htm