Spring Boot提供了对事务的全面支持。事务是指在数据库上执行的一系列操作,这些操作必须在单个、原子性的单位内执行,要么全部执行,要么全部回滚。在Spring Boot中,我们可以使用声明式事务管理来管理事务,这种方式可以极大地简化我们的代码,并将关注点从事务管理转移到业务逻辑上。本文将介绍Spring Boot中事务管理的基本概念和示例。
事务管理概述
在Spring Boot中,我们可以使用@Transactional注解来将方法标记为事务性方法。该注解可以应用于类级别和方法级别,当应用于类级别时,它将适用于该类中的所有方法。@Transactional注解提供了一些参数,可以用来定制事务的属性,例如事务的隔离级别、事务的传播行为、事务超时时间等。
在使用@Transactional注解时,我们需要确保该注解所在的类和方法在Spring容器中被声明为bean,因此通常需要将它们注解为@Component、@Service或@Repository。
Spring Boot默认使用Spring的声明式事务管理,它在底层使用了AOP技术。当我们在方法上标记@Transactional注解时,Spring会在方法调用前创建一个事务,并在方法调用后根据方法执行的结果,提交事务或者回滚事务。如果方法抛出了一个RuntimeException或者其子类的异常,事务会被回滚。如果方法执行成功,事务会被提交。此外,Spring还支持事务的嵌套、回滚规则等高级特性。
事务传播行为
在使用@Transactional注解时,我们可以使用propagation属性来指定事务的传播行为。传播行为用于描述一个事务方法执行过程中,如果该方法调用了其他事务方法,事务如何传播到被调用的方法。
以下是@Transactional注解中可用的传播行为:
- REQUIRED(默认):如果当前方法没有事务,就会新建一个事务,如果当前方法已经有事务,就使用当前事务。
- SUPPORTS:如果当前方法有事务,就使用当前事务,如果当前方法没有事务,就不使用事务。
- MANDATORY:如果当前方法有事务,就使用当前事务,如果当前方法没有事务,就抛出异常。
- REQUIRES_NEW:无论当前方法有没有事务,都会新建一个事务。
- NOT_SUPPORTED:当前方法不支持事务,如果当前方法有事务,会挂起该事务,等当前方法执行完毕后,再继续执行原来的事务。
- NEVER:当前方法不支持事务,如果当前方法有事务,就抛出异常。
- NESTED:如果当前方法有事务,就在该事务中创建一个嵌套事务,如果当前方法没有事务,就新建一个事务。
事务隔离级别
在使用@Transactional注解时,我们还可以使用isolation属性来指定事务的隔离级别。隔离级别用于描述一个事务对其他并发事务的影响。
以下是@Transactional注解中可用的隔离级别:
- DEFAULT(默认):使用数据库默认的隔离级别。
- READ_UNCOMMITTED:最低级别的隔离级别,允许一个事务读取另一个事务未提交的数据,会引发脏读、不可重复读和幻读问题。
- READ_COMMITTED:允许一个事务读取另一个事务已经提交的数据,可以防止脏读问题,但不可避免不可重复读和幻读问题。
- REPEATABLE_READ:保证一个事务多次读取同一数据时,读取到的数据是一致的,可以避免脏读和不可重复读问题,但不可避免幻读问题。
- SERIALIZABLE:最高级别的隔离级别,确保一个事务完全串行执行,可以避免所有并发问题,但性能最差。
事务超时
在使用@Transactional注解时,我们还可以使用timeout属性来指定事务的超时时间。超时时间用于描述一个事务最长等待的时间,超过该时间就会自动回滚事务。
以下是@Transactional注解中可用的超时时间:
- 默认值:表示不使用超时时间。
- 整数值:表示以秒为单位的超时时间。
事务回滚
在Spring Boot中,当事务方法抛出一个RuntimeException或者其子类的异常时,事务会自动回滚。除此之外,我们还可以使用编程式事务管理来手动回滚事务。编程式事务管理通常在需要在事务方法中进行条件判断或者异常处理时使用。
以下是编程式事务管理中常用的回滚方法:
- setRollbackOnly():将当前事务标记为回滚状态,这样事务在提交时就会回滚。
- TransactionAspectSupport.currentTransactionStatus().setRollbackOnly():将当前事务标记为回滚状态,这样事务在提交时就会回滚。该方法需要在@Transactional注解的方法中调用。