Spring 事务管理
Posted Do_GH
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring 事务管理相关的知识,希望对你有一定的参考价值。
文章目录
PlatformTransactionManager
spring框架也提供了一套完整的事务管理方案。其中主要以PlatformTransactionManager
类为核心类,该类提供了三个方法:
TransactionStatus getTransaction(TransactionDefinition definition)
根据指定的传播行为,返回当前活动的事务或创建一个新的事务,参数为TransactionDefinition
接口,该接口主要定义了事务传播的方式、隔离等级和事务超时时间。返回一个事务的状态TransactionStatus
类。commit(TransactionStatus status)
提交当前事务rollback(TransactionStatus status)
回滚当前事务
PlatformTransactionManager有三个实现类DataSourceTransactionManager
用于绑定jdbc数据源,HibernateTransactionManager
用于绑定Hibernate框架,JpaTransactionManager
TransactionDefinition
该类主要定义了事务传播方式、隔离等级和事务超时时间
属性
- 事务传播方式
传播方式 | 描述 | 值 |
---|---|---|
PROPAGATION_REQUIRED | 支持当前事务,如果当前没有事务,则创建一个新的事务 | 0 |
PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,则以非事务方式执行 | 1 |
PROPAGATION_MANDATORY | 支持当前事务,如果当前没有事务,就抛出异常 | 2 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起 | 3 |
PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起 | 4 |
PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常 | 5 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执行 如果当前没有事务则新建一个事务 | 6 |
- 事务隔离等级
spring定义的隔离级别与数据库相同,也分为4个级别作用效果也相同
隔离等级 | 描述 | 值 |
---|---|---|
ISOLATION_DEFAULT | 使用所使用默认数据库的隔离等级 | -1 |
ISOLATION_READ_UNCOMMITTED | 读未提交 | 1 |
ISOLATION_READ_COMMITTED | 读已提交 | 2 |
ISOLATION_REPEATABLE_READ | 可重复读 | 4 |
ISOLATION_SERIALIZABLE | 串行化 | 8 |
- 事务的超时时间
若某一事务在一定时间内未响应,则会直接回滚该事务
超时时间 | 描述 | 值 |
---|---|---|
TIMEOUT_DEFAULT | 默认超时时间(30秒) | -1 |
方法
int getIsolationLevel()
获取事务隔离等级(数值)String getName()
获取当前事务的名称int getPropagationBehavior()
获取事务的传播行为(数值)int getTimeout()
获取事务的超时时间Boolean isReadOnly()
是否优化为只读事务
SpringAPI事务管理方式
创建底层的spring的配置文件注册JDBC
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 创建数据库连接信息 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/os"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 扫描dao包下所有的注解 -->
<context:component-scan base-package="com.spring.transaction.dao"/>
</beans>
使用底层方法管理事务
再创建spring事务底层类的Bean实现
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 引入applicationContext配置 -->
<import resource="applicationContext.xml"/>
<!-- 注册事务管理平台,使用DataSourceTransactionManager实现类并指定数据源 -->
<bean id="transactionManagement" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="transactionDefinition" class="org.springframework.transaction.support.DefaultTransactionDefinition">
<!-- 注册事务传播行为类时,一般采用默认设置即可,如果需要修改可以设置property属性来进行修改-->
<property name="isolationLevelName" value="ISOLATION_DEFAULT"/>
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
<property name="timeout" value="30"/>
</bean>
</beans>
创建业务实现类
package com.spring.transaction.service.impl;
import com.spring.transaction.dao.OrderDao;
import com.spring.transaction.dao.ProductDao;
import com.spring.transaction.entity.Order;
import com.spring.transaction.entity.Product;
import com.spring.transaction.service.OrderService;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import javax.annotation.Resource;
import java.util.Date;
public class OrderServiceImpl implements OrderService
@Resource
private OrderDao orderDao;
@Resource
private ProductDao productDao;
@Resource
private PlatformTransactionManager transactionManager;
@Resource
private TransactionDefinition transactionDefinition;
public void addOrder(Order order)
// 创建事务
TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);
try
orderDao.insert(order);
Product product = productDao.select(order.getProductsId());
product.setStock(product.getStock() - order.getNumber());
productDao.update(product);
// 手动提交事务
transactionManager.commit(transaction);
catch (Exception e)
// 当触发异常时,回滚当前事务
e.printStackTrace();
transactionManager.rollback(transaction);
将需要处理的业务逻辑放在
try...catch...
中,如果在处理业务时发生了异常就可以调用rollback()
方法进行回滚
使用TransactionTemplate管理事务
创建一个新的spring配置,配置TransactionTemplate
的Bean类,该类是简化编程式事务界定和事务异常处理的模板类,它的核心方法为execute(org.springframework.transaction.support.TransactionCallback<T>)
,此模板处理事务生命周期和可能的异常,这样TransactionCallback实现和调用代码都不需要显式地处理事务。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 引入applicationContext配置 -->
<import resource="applicationContext.xml"/>
<!-- 添加自动扫描 -->
<context:component-scan base-package="com.spring.transaction.service"/>
<!-- 注册事务管理平台,使用DataSourceTransactionManager实现类并指定数据源 -->
<bean id="transactionManagement" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 使用TransactionTemplate管理事务,需要指定事务管理平台 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManagement"/>
</bean>
</beans>
TransactionTemplate
允许编写底层数据访问对象,这些对象使用诸如JDBC数据源之类的资源,但本身不支持事务。相反,它们可以隐式的参与高级应用程序服务利用该类处理的事务,并通过内部类回调对象调用低级服务。
package com.spring.transaction.service.impl;
import com.spring.transaction.dao.OrderDao;
import com.spring.transaction.dao.ProductDao;
import com.spring.transaction.entity.Order;
import com.spring.transaction.entity.Product;
import com.spring.transaction.service.OrderService;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
public class OrderServiceImpl1 implements OrderService
@Resource
private OrderDao orderDao;
@Resource
private ProductDao productDao;
@Resource
private TransactionTemplate transactionTemplate;
public void addOrder(final Order order)
transactionTemplate.execute(new TransactionCallback<Object>()
public Object doInTransaction(TransactionStatus transactionStatus)
orderDao.insert(order);
Product product = productDao.select(order.getProductsId());
product.setStock(product.getStock() - order.getNumber());
productDao.update(product);
return null;
);
Spring 声明式管理事务
除了使用API的形式显示的方法管理事务,spring还提供在配置文件中声明管理事务。这种方法主要建立在AOP的基础之上,本质上就是对需要进行事务管理的方法进行拦截,对其增强。这样业务层的实现类就会更加简便,方便后期维护。
基于TransactionInterceptor的事务管理
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 引入applicationContext配置 -->
<import resource="applicationContext.xml"/>
<!-- 添加自动扫描 -->
<context:component-scan base-package="com.spring.transaction.service"/>
<!-- 注册事务管理平台,使用DataSourceTransactionManager实现类并指定数据源 -->
<bean id="transactionManagement" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 注册实现类 -->
<bean id="orderServiceTarget" class="com.spring.transaction.service.impl.OrderServiceImpl"/>
<!-- 设置事务拦截器 -->
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!-- 设置事务管理器 -->
<property name="transactionManager" ref="transactionManager"/>
<!-- 设置事务属性,使用props标签利用键值对的形式为属性赋值,key描述实现类的方法,支持通配符 -->
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<!-- 使用代理类,设置目标类,并增加拦截器 -->
<bean id="orderService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="orderServiceTarget"/>
<!-- 如果有多个拦截器使用list标签 -->
<property name="interceptorNames">
<list>
<idref bean="transactionInterceptor"/>
</list>
</property>
</bean>
</beans>
简单来说就是利用AOP对业务实现类进行增强,只需要创建TransactionInterceptor的实例并配置事务属性即可
基于TransactionProxyFactoryBean声明事务
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 引入applicationContext配置 -->
<import resource="applicationContext.xml"/>
<!-- 添加自动扫描 -->
<context:component-scan base-package="com.spring.transaction.service"/>
<!-- 注册事务管理平台,使用DataSourceTransactionManager实现类并指定数据源 -->
<bean id="transactionManagement" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 注册实现类 -->
<bean id="orderServiceTarget" class="com.spring.transaction.service.impl.OrderServiceImpl"/>
<!-- 使用事务的代理类,更为简便的设置事务属性和需要增强的目标类 -->
<bean id="orderService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
<!-- 指定需要增强的目标类 -->
<property name="target" ref="orderServiceTarget"/>
</bean>
</beans>
基于<tx>命名空间声明事务
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 引入applicationContext配置 -->
<import resource="applicationContext.xml"/>
<!-- 添加自动扫描 -->
<context:component-scan base-package="com.spring.transaction.service"/>
<!-- 注册事务管理平台,使用DataSourceTransactionManager实现类并指定数据源 -->以上是关于Spring 事务管理的主要内容,如果未能解决你的问题,请参考以下文章
Spring事务看这一篇就够了!!(Spring事务特征+Spring事务管理+实现+Spring七种事务传播行为+集成MyBatis)
Spring事务看这一篇就够了!!(Spring事务特征+Spring事务管理+实现+Spring七种事务传播行为+集成MyBatis)