@Transactional transaction propagation

@Transactional transaction propagation

raw table data

image-20230701191818135

@Transactional() controls the configuration item of transaction propagation (default Propagation.REQUIRED)

@Transactional(propagation=Propagation.REQUIRED)           //控制事务传播。默认是Propagation.REQUIRED
@Transactional(isolation=Isolation.DEFAULT)                //控制事务隔离级别。默认跟数据库的隔离级别相同
@Transactional(readOnly=false)                             //控制事务可读写、只可读。默认可读写
@Transactional(timeout=30)                                 //控制事务的超时时间,单位秒。默认跟数据库的事务控制系统相同
@Transactional(rollbackFor=RuntimeException.class)         //控制事务遇到哪些异常会回滚。默认是RuntimeException
@Transactional(rollbackForClassName=RuntimeException)      //同上
@Transactional(noRollbackFor=NullPointerException.class)   //控制事务遇到哪些异常不会回滚。默认遇到RuntimeException回滚
@Transactional(noRollbackForClassName=NullPointerException)//同上

We will use the default @Transactionalannotation this time without adding any parameters.

And do not use **try{}catch{}** to catch exceptions.

similar call method

Similar A method calls B method

1. Both method A and method B of the same type have @Transactionalannotations

@Service
public class A_Service {
    
    
    @Resource
    UserMapper userMapper;
    
	@Transactional
    public void A(){
    
    
        User user = new User();
        user.setId(5);
        user.setEmail("A");
        userMapper.updateById(user);
        B();
    }

    @Transactional
    public void B(){
    
    
        User user = new User();
        user.setId(5);
        user.setEmail("B");
        userMapper.updateById(user);
        throw new RuntimeException("B方法业务异常");
    }
}

Then test the method using the test class

@SpringBootTest
public class TransactionalTest {
    
    
    @Resource
    A_Service a_Service;

    @Test
    public void test(){
    
    
        a_Service.A();
    }
}

operation result

image-20230701193714501

Then check if the database data is rolled back

image-20230701193847889

You can see that the data has been rolled back

When method A and method B of the same type @Transactionalare annotated, when method A calls method B, method B has its own transactions, but method A also has transactions, and method B will be added to the transactions of method A.

Therefore, if an exception occurs anywhere in A or B, it will be rolled back.

2. Method A has @Transactionalannotations, method B does not

Modify method B :

    public void B(){
    
    
        User user = new User();
        user.setId(5);
        user.setEmail("B");
        userMapper.updateById(user);
        throw new RuntimeException("B方法业务异常");
    }

Test again, and then see if the database data is rolled back

image-20230701193847889

When the same type A method @Transactionalis annotated, when the B method does not have it, when the A method calls the B method, the A method has a transaction, but the B method does not, and the B method will be added to the transaction of the A method.

Therefore, if an exception occurs anywhere in A or B, it will be rolled back.

3. Method A has no @Transactionalannotations, method B has @Transactionalannotations

Modify A method

public void A(){
    
    
    User user = new User();
    user.setId(5);
    user.setEmail("A");
    userMapper.updateById(user);
    b_service.B();
}

Test again, and then see if the database data is rolled back

image-20230701202200706

It can be seen that the data has been modified by both method A and method B.

It shows that when the same type of B method is called by A method, B method finds that A method has no transaction. So your own transaction will not take effect, so neither SQL is rolled back.

Heterogeneous call method

A class A method calls B class B method

@Transactional1. There are annotations for Class A method and Class B method

Class A:

@Service
public class A_Service {
    
    
    @Resource
    UserMapper userMapper;

    @Resource
    B_Service b_service;

    @Transactional
    public void A(){
    
    
        User user = new User();
        user.setId(5);
        user.setEmail("A");
        userMapper.updateById(user);
        b_service.B();
    }
}

Class B:

@Service
public class B_Service {
    
    
    @Resource
    UserMapper userMapper;

    @Transactional
    public void B(){
    
    
        User user = new User();
        user.setId(5);
        user.setEmail("B");
        userMapper.updateById(user);
        throw new RuntimeException("B方法业务异常");
    }
}

Then test the method using the test class

@SpringBootTest
public class TransactionalTest {
    
    
    @Resource
    A_Service a_Service;

    @Test
    public void test(){
    
    
        a_Service.A();
    }
}

operation result

image-20230701193714501

Then check if the database data is rolled back

image-20230701193847889

You can see that the data has been rolled back

When the A method of class A and the B method of class B @Transactionalare annotated, when the B method of B class is called, the B method has its own transaction, but the A method also has a transaction, and the B method will be added to the transaction of the A method.

Therefore, if an exception occurs anywhere in A or B, it will be rolled back.

2. The A method of class A has @Transactionalannotations, but the B method of class B does not

Modify B class B method :

    public void B(){
    
    
        User user = new User();
        user.setId(5);
        user.setEmail("B");
        userMapper.updateById(user);
        throw new RuntimeException("B方法业务异常");
    }

Test again, and then see if the database data is rolled back

image-20230701193847889

You can see that the data has been rolled back

When the A method of class A has @Transactionalannotations, the B method of class B does not.

When method A of class A calls method B of class B, method B of class B will join the transaction of method A of class A. So class B and method B report an error, and the SQL of the two methods will all be rolled back.

If the exception is after calling the B class B method, if an exception occurs in the A class A method or the B class B method, the transaction will be rolled back.

3. A method of class A has no @Transactionalannotations, and method B of class B has @Transactionalannotations

Modify A class A method

public void A(){
    
    
    User user = new User();
    user.setId(5);
    user.setEmail("A");
    userMapper.updateById(user);
    b_service.B();
}

Test again, and then see if the database data is rolled back

image-20230701195710127

It can be seen that the data is modified by method A of class A, but the data of method B of class B is rolled back

It shows that when the method B of class B is called by the method A of class A, the method B of class B finds that the method A of class A has no transaction, but it will create a transaction if it has a transaction, but the method A of class A will still not roll back.

If the exception occurs after calling method B of class B , and an exception occurs in method A of class A, then both the SQL of method A and method B will be executed, and the transaction will not be rolled back.

Summarize

We found that similar and heterogeneous transactions are roughly the same. For example, both Class A method A and Class B B method have @Transactionalannotations, and Class A A method has @Transactionalannotations, and Class B B methods have the same effect without annotations.

But there is one difference: the same type A method has no @Transactionalannotations, the B method has @Transactionalannotations, and the A type A method has no @Transactionalannotations, and the B type B method has @Transactionalannotations, and the obtained results are different.

This test is over

Guess you like

Origin blog.csdn.net/m0_57647880/article/details/131494624