Spring中事务管理
1、传统编程式事务管理
2、声明式事务管理(aop实现)。
编程式事务:是指在代码中手动的管理事务的提交、回滚等操作,代码侵入性比较强,如下示例:
try {声明式事务:基于AOP面向切面的,它将具体业务与事务处理部分解耦,代码侵入性很低,所以在实际开发中声明式事务用的比较多。
//TODO something
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
throw new InvoiceApplyException("异常失败");
}
声明式事务也有两种实现方式,一是基于tx和AOP的xml配置文件方式,二是就是基于@Transactional注解。
基于xml形式声明事物管理
<?xml version="1.0"
encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!--spring aop 声明式事务管理--> <!-- 1.数据源事物管理器DataSourceTransactionManager,依赖数据源 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 数据源 --> <property name="dataSource"
ref="dataSource"/> </bean> <!-- 2.通知 :通知是切面的一种功能实现,可以完成简单的织入功能。 --> <tx:advice id="txAdvice"
transcation-manager="transactionManager"> <tx:atrributes> <!-- 传播行为 传播 propagation--> <tx:method name="save"
propagation="REQUIRED"/> <tx:method name="insert*"
propagation="REQUIRED" /> <tx:method name="add*"
propagation="REQUIRED" /> <tx:method name="create*"
propagation="REQUIRED" /> <tx:method name="delete*"
propagation="REQUIRED" /> <tx:method name="update*"
propagation="REQUIRED" /> <tx:method name="find*"
propagation="SUPPORTS" read-only="true" /> <tx:method name="select*"
propagation="SUPPORTS" read-only="true" /> <tx:method name="get*"
propagation="SUPPORTS" read-only="true" /> </tx:atrributes> </tx:advice> <!-- 3.通知器、增强器 :将切入点与通知整合 ,,,切面表达式是aspectJ的--> <aop:config> <!-- Advisor(通知器) Spring通知器(advisor)=通知(advice)+切入点(PointCut) 切面表达式:execution(*
com.lx.service.*.*(..)) --> <aop:advisor advice-ref="txAdvice"
pointcut="execution(*
com.lx.service.*.*(..))"/> </aop:config> </beans> |
基于注解的声明事物管理
XMl进行事物配置
<!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--开启事务的Annotation支持 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
在需要进行事物的方法或类上加@Transactional
|
事务的传播机制和隔离机制
@Transactional属性
propagation : 事务的传播行为
readOnly : 事务的读写属性,取true或者false,true为只读、默认为false
rollbackFor : 回滚策略,当遇到指定异常时回滚。譬如上例遇到异常就回滚
timeout (补充的) : 设置超时时间,单位为秒
isolation : 设置事务隔离级别,枚举类型,一共五种
demo
复制收展Javapublic class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Transactional(propagation = Propagation.SUPPORTS, readOnly = false, rollbackFor = Exception.class, timeout = 3000, isolation = Isolation.DEFAULT)
public int deleteByName(String name) {
int result = userDao.deleteByName(name);
return result;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
事务的传播行为
事务传播行为类型 |
说明 |
PROPAGATION_REQUIRED |
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 |
PROPAGATION_SUPPORTS |
支持当前事务,如果当前没有事务,就以非事务方式执行。 |
PROPAGATION_MANDATORY |
使用当前的事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW |
新建事务,如果当前存在事务,把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED |
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NEVER |
以非事务方式执行,如果当前存在事务,则抛出异常 |
PROPAGATION_NESTED |
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类 似的操作 |
大写看着不习惯,小写对应上面的,顺便翻译一下字面的意思
propagation_required 传播需要
propagation_supports 传播支持
propagation_mandatory 强制传播
propagation_requires_new 传播需要新的
propagation_not_supported 不支持传播
propagation_never 绝不传播
propagation_nested 嵌套传播
事务隔离级别
类型 |
说明 |
DEFAULT |
采用数据库默认隔离级别 |
READ_UNCOMMITTED |
读未提交的数据(会出现脏读取) |
READ_COMMITTED |
读已提交的数据(会出现幻读,即前后两次读的不一样) |
REPEATABLE_READ |
可重复读,会出现幻读 |
SERIALIZABLE 串行化 |
(对资源消耗较大,一般不使用) |
default
read_uncommitted
read_committed
repeatable-read
serializable
更详细的可参考
@Transactional失效场景
1、数据库引擎设置不对造成的。
2、入口的方法必须是public,否则事务不起作用。
3、Spring的事务管理默认只对出现运行期异常(java.lang.RuntimeException及其子类)进行回滚
4、类是否被代理了