上一篇地址:赶紧收藏!2024 年最常见 100道 Java 基础面试题(四十八)-CSDN博客
九十七、spring事务实现方式有哪些?
Spring框架提供了多种事务管理的实现方式,以支持不同的事务需求和场景。以下是Spring支持的几种主要事务实现方式:
-
编程式事务管理:
- 通过直接编写代码来管理事务的边界和行为。Spring提供了
TransactionTemplate
类,它允许你以编程方式轻松地管理事务。
javaTransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); transactionTemplate.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { // 执行业务操作 } });
- 通过直接编写代码来管理事务的边界和行为。Spring提供了
-
声明式事务管理:
-
利用AOP(面向切面编程),将事务管理逻辑与业务逻辑分离。声明式事务通过配置来指定哪些方法需要事务管理,以及事务的传播行为等。
-
基于XML的声明式事务: 使用传统的XML配置来声明事务管理器和事务属性。
XML<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.example.*Service.*(..))"/> </aop:config>
-
基于注解的声明式事务 : 使用
@Transactional
注解来声明事务管理。
java@Transactional public void myMethod() { // 执行业务操作 }
-
-
Spring Data JPA:
- Spring Data JPA提供了简化的事务管理,特别是对于JPA(Java Persistence API)操作。它使用
@Transactional
注解来声明事务。
- Spring Data JPA提供了简化的事务管理,特别是对于JPA(Java Persistence API)操作。它使用
-
JTA(Java Transaction API):
- 对于复杂的、跨多个资源管理器的事务(如跨多个数据库或JMS队列),可以使用JTA。Spring支持通过JTA进行全局事务管理。
-
Spring Boot的自动配置事务:
- 在Spring Boot应用中,事务管理通常由Spring Boot的自动配置机制来完成。开发者只需添加相应的依赖,并使用
@Transactional
注解即可。
- 在Spring Boot应用中,事务管理通常由Spring Boot的自动配置机制来完成。开发者只需添加相应的依赖,并使用
-
反应式事务管理:
- 对于反应式编程,Spring提供了反应式事务管理支持。这允许在反应式流中进行事务管理。
-
自定义事务管理器:
- 如果现有的事务管理器不能满足特定需求,可以自定义事务管理器。通过实现
PlatformTransactionManager
接口,可以创建特定技术的事务管理器。
- 如果现有的事务管理器不能满足特定需求,可以自定义事务管理器。通过实现
每种事务管理方式都有其特定的使用场景和优缺点。例如,编程式事务管理适合于细粒度的控制,而声明式事务管理则更适合于保持业务逻辑的清晰和简洁。在实际应用中,开发者应根据项目的具体需求和复杂度来选择最合适的事务管理方式。
此外,事务的实现还依赖于底层的事务管理技术,如JDBC、JTA、JPA、Hibernate等。Spring框架提供了一个抽象层,允许开发者以统一的方式处理不同的事务管理技术。
九十八、说一下spring的事务隔离?
在Spring框架中,事务隔离级别是数据库事务的一个重要概念,它定义了在并发环境下事务如何与其他事务隔离,以防止数据的不一致性和冲突。Spring支持多种事务隔离级别,这些级别是由底层数据库的事务隔离级别所支持的。
以下是数据库通常支持的事务隔离级别:
-
READ_UNCOMMITTED (读未提交):
- 这是最低的隔离级别。允许事务读取未被其他事务提交的更改。这可能会导致"脏读"(Dirty Read),即读到的数据可能最终不会被提交。
-
READ_COMMITTED (读已提交):
- 事务只能读取已经提交的数据。在该隔离级别下,可以避免脏读,但仍然可能会出现"不可重复读"(Non-repeatable Read),即同一个事务中两次读取到的数据可能不同。
-
REPEATABLE_READ (可重复读):
- 确保在一个事务的执行期间看到的数据保持不变,即使其他事务在该事务执行期间提交了更改。在该隔离级别下,可以避免不可重复读,但仍然可能会出现"幻读"(Phantom Read),即同一个事务中两次读取满足相同查询条件的记录数可能不同。
-
SERIALIZABLE (串行化):
- 最高的隔离级别。事务被处理得就像是依次一个接一个地执行的,因此可以防止脏读、不可重复读和幻读。但这种隔离级别也大大降低了并发性能。
Spring框架允许你通过配置来设置事务的隔离级别。以下是如何在Spring中设置事务隔离级别的示例:
基于XML的配置:
java
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionAttributes" class="org.springframework.transaction.config.MethodMapTransactionAttributeSource">
<property name="methodMap">
<map>
<entry key="myMethod">
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttribute" ref="myTransactionAttribute" />
</bean>
</entry>
</map>
</property>
</bean>
<bean id="myTransactionAttribute" class="org.springframework.transaction.interceptor.DefaultTransactionAttribute">
<property name="isolation" value="ISOLATION_REPEATABLE_READ" />
<!-- 其他事务属性 -->
</bean>
基于注解的配置:
java
@Configuration
@EnableTransactionManagement
public class AppConfig {
@Bean
public TransactionManager transactionManager() {
// 设置事务管理器,例如使用JPA或JDBC
}
@Bean
public TransactionAttributeSource transactionAttributeSource() {
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
DefaultTransactionAttribute txAttr = new DefaultTransactionAttribute();
txAttr.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
// 其他事务属性
source.addTransactionalMethod("myMethod", txAttr);
return source;
}
}
在实际应用中,选择合适的事务隔离级别是一个权衡过程,需要考虑数据的一致性和并发性能。通常,READ_COMMITTED
是默认的隔离级别,因为它提供了较好的平衡。然而,在某些需要严格一致性的场景下,可能需要选择更高的隔离级别。需要注意的是,提高隔离级别可能会降低数据库的并发能力。因此,选择隔离级别时,应充分了解业务需求和性能影响。