基础理解
基本概念 事务:是一组原子性的数据库操作,要么全部成功,要么全部失败。 ACID:事务需要满足原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。 事务管理的两种方式 编程式事务管理:通过编码的方式管理事务,使用 TransactionTemplate 或 PlatformTransactionManager。 声明式事务管理:通过注解或 XML 配置来管理事务,更常见且易于使用。 使用 @Transactional 注解 在 Spring Boot 中,声明式事务管理通常是通过 @Transactional 注解来实现的。这个注解可以添加到类或方法上。 添加到类上:类中的所有方法都会拥有相同的事务属性。 添加到方法上:只有被注解的方法会使用指定的事务属性。 配置事务属性 @Transactional 注解支持多种属性,如: propagation:事务的传播行为。 isolation:事务的隔离级别。 timeout:事务的超时时间。 readOnly:指定事务是否为只读。 rollbackFor:指定哪些异常会导致事务回滚。 noRollbackFor:指定哪些异常不会导致事务回滚。 事务传播行为 REQUIRED:默认行为,如果存在事务,就加入事务;否则,创建一个新的事务。 REQUIRES_NEW:创建一个新的事务,如果存在事务,将当前事务挂起。 PROPAGATION_NOT_SUPPORTED:非事务的执行,如果存在事务,将抛出异常。 隔离级别 READ_UNCOMMITTED READ_COMMITTED REPEATABLE_READ (mysql 默认) SERIALIZABLE 处理事务异常 事务在遇到运行时异常时默认会回滚,但你可以自定义回滚规则。
事务失效的场景
方法的可见性问题 事务方法没有经过Spring代理对象,导致事务失效。
java"> @Service public class MyService { @Transactional public void myTransactionalMethod ( ) { } public void myNonTransactionalMethod ( ) { myTransactionalMethod ( ) ; }
}
自调用 在同一个类中,一个方法内部调用了另一个带有 @Transactional 注解的方法,事务不会启动。
java">@Service
public class MyService { @Transactional public void myTransactionalMethodA ( ) { myTransactionalMethodB ( ) ; } @Transactional public void myTransactionalMethodB ( ) { }
}
java">@Service
public class MyService { @Transactional public void myTransactionalMethod ( ) { }
}
MyService myService = new MyService ( ) ;
myService. myTransactionalMethod ( ) ;
异常未被正确抛出 事务方法内部抛出的异常没有被正确捕获和处理,导致事务没有回滚。
java">@Service
public class MyService { @Transactional public void myTransactionalMethod ( ) { if ( true ) { throw new RuntimeException ( "Error occurred" ) ; } }
}
java">@Service
public class MyService { @Transactional ( propagation = Propagation . REQUIRES_NEW) public void myTransactionalMethodA ( ) { myTransactionalMethodB ( ) ; } public void myTransactionalMethodB ( ) { }
}
数据库不支持事务 多个事务管理器 在有多个事务管理器的情况下,没有指定正确的事务管理器。
java">@Configuration
@EnableTransactionManagement
public class TransactionConfig { @Bean public PlatformTransactionManager txManager1 ( ) { return new DataSourceTransactionManager ( dataSource1) ; } @Bean public PlatformTransactionManager txManager2 ( ) { return new DataSourceTransactionManager ( dataSource2) ; }
} @Service
public class MyService { @Transactional ( value = "txManager1" , propagation = Propagation . REQUIRES_NEW) public void myTransactionalMethodA ( ) { }
}
异步方法 在 @Transactional 方法中启动了新的线程执行任务,新线程中的任务不会继承原方法的事务上下文。
java">@Service
public class MyService { @Transactional public void myTransactionalMethod ( ) { new Thread ( ( ) -> { } ) . start ( ) ; }
}
超时设置 事务运行时间超过了设置的超时时间,导致事务被数据库自动回滚。
java">@Service
public class MyService { @Transactional ( timeout = 1 ) public void myTransactionalMethod ( ) { }
}