面试题答案
一键面试- 确保整体事务执行及异常回滚:
- 在Spring Boot中,可以使用声明式事务管理来确保
methodA
和methodB
中的数据库操作作为一个整体事务执行。当methodB
出现异常时,整个事务会自动回滚,前提是异常是未被捕获的运行时异常(RuntimeException
及其子类)。如果是检查型异常(Exception
及其子类,但不包括RuntimeException
),需要手动配置事务管理器来使其触发回滚。
- 在Spring Boot中,可以使用声明式事务管理来确保
- Kotlin代码中配置和实现事务管理:
- 添加依赖:在
build.gradle.kts
文件中确保有Spring Boot事务管理相关依赖,一般Spring Boot Starter Data模块(如spring - boot - starter - jdbc
或spring - boot - starter - data - jpa
等)已经包含了事务管理相关依赖。 - 配置事务管理器:
- 如果使用JDBC,在
application.yml
中配置数据源,然后创建一个DataSourceTransactionManager
的Bean。例如:
- 如果使用JDBC,在
- 添加依赖:在
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.jdbc.datasource.DataSourceTransactionManager
import org.springframework.transaction.PlatformTransactionManager
import javax.sql.DataSource
@Configuration
class TransactionConfig {
@Bean
fun transactionManager(dataSource: DataSource): PlatformTransactionManager {
return DataSourceTransactionManager(dataSource)
}
}
- 如果使用JPA,Spring Boot会自动配置`JpaTransactionManager`,一般无需额外配置。
- 声明事务:
- 在
ServiceA
的methodA
上使用@Transactional
注解。例如:
- 在
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
@Service
class ServiceA {
private val serviceB: ServiceB
constructor(serviceB: ServiceB) {
this.serviceB = serviceB
}
@Transactional
fun methodA() {
// 数据库操作
serviceB.methodB()
// 更多数据库操作
}
}
- `ServiceB`的`methodB`无需额外的`@Transactional`注解,因为它会加入到`methodA`开启的事务中。
3. 事务传播行为的选择及原因:
- 默认的事务传播行为是
PROPAGATION_REQUIRED
。在这种情况下,当methodA
调用methodB
时:- 如果当前没有事务(
methodA
不是在事务内被调用),methodA
会开启一个新事务,methodB
加入到这个事务中。 - 如果当前已经有事务(
methodA
是在事务内被调用),methodB
直接加入到这个事务中。
- 如果当前没有事务(
- 选择
PROPAGATION_REQUIRED
的原因是,希望methodA
和methodB
中的数据库操作在同一个事务上下文中执行,确保数据的一致性。当methodB
出现异常时,整个事务(包括methodA
中的操作)回滚,避免部分数据操作成功而部分失败导致的数据不一致问题。