@Transactional transaction propagation
raw table data
@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 @Transactional
annotation 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 @Transactional
annotations
@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
Then check if the database data is rolled back
You can see that the data has been rolled back
When method A and method B of the same type
@Transactional
are 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 @Transactional
annotations, 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
When the same type A method
@Transactional
is 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 @Transactional
annotations, method B has @Transactional
annotations
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
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
@Transactional
1. 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
Then check if the database data is rolled back
You can see that the data has been rolled back
When the A method of class A and the B method of class B
@Transactional
are 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 @Transactional
annotations, 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
You can see that the data has been rolled back
When the A method of class A has
@Transactional
annotations, 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 @Transactional
annotations, and method B of class B has @Transactional
annotations
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
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 @Transactional
annotations, and Class A A method has @Transactional
annotations, and Class B B methods have the same effect without annotations.
But there is one difference: the same type A method has no @Transactional
annotations, the B method has @Transactional
annotations, and the A type A method has no @Transactional
annotations, and the B type B method has @Transactional
annotations, and the obtained results are different.
This test is over