spring的事务详解

本文深入解析Spring事务管理机制,涵盖事务的基本概念、四大特性、事务管理接口与实现、隔离级别、传播行为等内容,并介绍了编程式与声明式事务管理的具体实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果不想看概念的话,直接跳到编程式事务管理(ctrl+F)那里开始

事务的四大特性:

原子性,一致性,隔离性,持久性

原子性是指事务是一个不可分割的工作单位,十五中的操作要么都发生,要么都不发生。

一致性是指事务前后数据的完整性必须保持一致。

隔离性是指多个用户并发访问数据库时,一个用户的食物不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离。

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,即使数据库发生故障也不应该对齐有任何影响。

 

Spring事务管理高层抽象主要包括3个接口

PlatformTransactionManager(事务管理器)

TransactionDefinition(事务定义信息[隔离,传播,超时,只读])

TransactionStatus(事务具体运行状态)

 

PlatformTransactionManager接口实现

Org.springframework.jdbc.datasource.DataSourceTransactionManager(使用spring jdbc或ibatis进行持久化数据时使用)

Org.springframework.orm.hibernate3.HibernateTransactionManager(使用Hibernate3.0版本进行持久化数据)

Org.springframework.orm.jpa.JpaTransactionManager(使用JPA进行持久化时使用)

Org.springframework.jdo.JdoTransactionManager(当持久化机制是Jdo时使用)

Org.springframework.transaction.jta.JtaTransationManager(使用一个JTA实现来管理事务,在一个事务跨越多个资源时必须使用)

 

如果不考虑隔离性,会引发安全问题:

脏读,不可重复读,幻读

脏读:一个事务读取了另一个事务改写但还未提交的数据,如果这些数据被回滚,则读到的数据是无效的

不可重复读:在同一事务中,多次读取同一数据返回的结果有所不同

幻读:一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了,再后来的查询中,第一个事务就会发现有些原来没有的记录

 

事务隔离级别(四种)

Default(使用后端数据库默认的隔离级别)

READ_UNCOMMITED(允许你读取还未提交的改变了的数据。可能导致脏,幻,不可重复读)

READ_COMMITTED(允许在并发事务已经提交后读取,可防止脏读,但幻读和不可重复读仍会发生)

REPEATABLE_READ(对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏,不可重复读,但幻读扔可能发生)

SERIALIZABLE(完全服从ACID的隔离级别,确保不发生脏,幻,不可重复读,这在所有隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的)

 

PS:

Mysql默认采用REPEATABLE_READ隔离级别

Oracle默认采用READ_COMMITTED隔离级别

 

事务的传播行为(七种):

PROPAGATION_REQUIRED(支持当前事务,如果不存在,就新建一个)

PROPAGATION_SUPPORTS(支持当前事务,如果不存在,就不使用事务)

PROPAGATION_MANDATORY(支持当前事务,如果不存在,抛出异常)

PROPAGATION_REQUIRES_NEW(如果有事务存在,挂起当前事务,创建一个新的事务)

PROPAGATION_NOT_SUPPORTED(以非事务方式运行,如果有事务存在,挂起当前事务)

PROPAGATION_NEVER(以非事务方式运行,如果有事务存在,跑出异常)

PROPAGATION_NESTED(如果当前事务存在,则嵌套事务执行)

 

Spring支持两种方式事务管理

--编程式的事务管理(一种)

       *在实际应用中很少使用

       *通过TransactionTemplate手动管理事务

--使用XML配置声明式事务(三种)

       *开发中推荐使用(代码入侵性最小)

       *Spring的声明式事务是通过AOP实现的

 

编程式的事务管理:

Spring文件配置

<!--配置事务管理器 -->
<bean id=”transactionManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionMnager”>
<property name=”dataSource” ref=”dataSource”/>
</bean>

<!--配置事务管理的模板 -->
<bean id=”transactionTemplate” class=”org.springframework.transaction.support. TransactionTemplate”>
<property name=”transactionManager” ref=”transactionManager”/>
</bean>

<!--配置业务层类-->
<bean id=”accountService” class=”cn.muke.spring.demo1.AccountServiceImpl”>
<property name=”accountDao” ref=”accountDao”/>
<!--注入事务管理的模板 -->
<property name=”transactionTemplate” ref=”transactionTemplate”/>
</bean>

在业务实现类里面(serviceimpl)

//注入事务管理的模板:
Private TransactionTemplate transactionTemplate;

Public void transfer(String out,String in,double money){
TransactionTemplate.execute(new TransactionCallbackWithoutResult(){
Protected void doInTransactionWithoutResult(TransactionStatus transactionStatus){
AccountDao.outMoney(out,money);
Int i=1/0;
AccountDao.inMoney(in,money);
}
});
}
执行这个方法会失败,因为1/0会错误所以会回滚

声明式事务管理方式一:基于TransactionProxyFactoryBean的方式

Spring文件配置

<!--配置事务管理器 -->
<bean id=”transactionManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionMnager”>
<property name=”dataSource” ref=”dataSource”/>
</bean>

<!--配置业务层的代理-->
<bean id=”accountServiceProxy”class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”>
<!--配置目标对象-->
<property name=”target” ref=”accountService”/>
<!--注入事务管理器 -->
<property name=”transactionManager” ref=”transactionManager”/>
<!--注入事务属性 -->
<property name=”transactionAttributes”>
<props>
<!--prop的格式:
*代表类中所有方法 
*PROPAGATION :事务的传播行为
*ISOLATION:事务的隔离级别
*readOnly:只读(不可以进行插入,修改删除)
*-Exception:发生哪些异常回滚事务
*+Exception:发生哪些异常不回滚事务
-->
<prop key=”transfer”> PROPAGATION </prop>
</props>
</property>
</bean>

声明式事务管理方式二:基于AspectJ的XML方式

Spring文件配置

<!--配置事务管理器 -->
<bean id=”transactionManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionMnager”>
<property name=”dataSource” ref=”dataSource”/>
</bean>

<!--配置事务的通知:(事务的增强)-->
<tx:advice id=”txAdvice”transaction-manager=”transactionManager”>
<tx:attributes>
<!--
	Propagation:事务传播行为
	Isolation:事务隔离级别
	Read-only:只读
	Rollback-for:发生哪些异常回滚
	No-rollback-for:发生哪些异常不会滚
	Timeout”过期信息
 -->

<tx:method name=”transfer” propagation=”REQUIRED”/>
</tx:attributes>
</ tx:advice >

<!--配置切面-->
<aop:config>
<!--配置切入点-->
<aop:pointcut expression=”execution(* cn.muke.spring.demo3.AccountService+.*(..))” id=”pointcut1”>
<!--配置切面-->
<aop:advisor advice-ref=”txAdvice” pointcut-ref=”pointcut1”/>
</aop:config>

声明式事务管理方式三:基于注解方式

Spring文件配置

<!--配置事务管理器 -->
<bean id=”transactionManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionMnager”>
<property name=”dataSource” ref=”dataSource”/>
</bean>

<!--开启注解事务 -->
<tx:annotation-driven transaction-manager=”transactionManager”/>

在业务实现类里面(serviceimpl)

加上@Transactional即可
@Transactiona注解中的属性
Propagation:事务的传播行为
Isolation:事务的隔离级别
ReadOnly:只读
RollbackFor:发生哪些异常回滚
NoRollbackFor:发生哪些异常不回滚
例如:Transactiona(propagation=Propagation.REQUIRED,isolation=Isolation.Default)
总结:
--编程式的事务管理
	*通过TransactionTemplate手动管理事务(很少使用)
--使用XML配置声明式事务
	*基于TransactionProxyFactoryBean的方式(很少使用)
		*需要为每个进行事务管理的类,配置一个TransactionProxyFactoryBean进行增强
	*基于AspectJ的XML方式(经常使用)
		*一旦配置好了,需要在类上加任何东西
	*基于注解方式(经常使用)
		*配置简单。需要在业务类上添加一个@Transactiona的注解










资源下载链接为: https://pan.quark.cn/s/f989b9092fc5 HttpServletRequestWrapper 是 Java Servlet API 中的一个工具类,位于 javax.servlet.http 包中,用于对 HttpServletRequest 对象进行封装,从而在 Web 应用中实现对 HTTP 请求的拦截、修改或增强等功能。通过继承该类并覆盖相关方法,开发者可以轻松地自定义请求处理逻辑,例如修改请求参数、添加请求头、记录日志等。 参数过滤:在请求到达处理器之前,可以对请求参数进行检查或修改,例如去除 URL 编码、过滤敏感信息或进行安全检查。 请求头操作:可以修改或添加请求头,比如设置自定义的 Content-Type 或添加认证信息。 请求属性扩展:在原始请求的基础上添加自定义属性,供后续处理使用。 日志记录:在处理请求前记录请求信息,如 URL、参数、请求头等,便于调试监控。 跨域支持:通过添加 CORS 相关的响应头,允许来自不同源的请求。 HttpServletRequestWrapper 通过继承 HttpServletRequest 接口并重写其方法来实现功能。开发者可以在重写的方法中添加自定义逻辑,例如在获取参数时进行过滤,或在读取请求体时进行解密。当调用这些方法时,实际上是调用了包装器中的方法,从而实现了对原始请求的修改或增强。 以下是一个简单的示例,展示如何创建一个用于过滤请求参数的包装器: 在 doFilter 方法中,可以使用 CustomRequestWrapper 包装原始请求: 这样,每当调用 getParameterValues 方法时,都会先经过自定义的过滤逻辑。 HttpServletRequestWrapper 是 Java Web 开发中一个强大的工具,它提供了灵活的扩展性,允许开发者
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值