Spring 声明式事务中使用注解@Transactional的方式、原理及注意事项
来源:互联网 发布:手机动漫模型软件 编辑:程序博客网 时间:2024/05/24 05:46
本文主要讨论Spring声明式事务中使用注解@Transactional的方式、原理及注意事项,主要包括以下内容:
- Spring @Transactional的配置使用;
- Spring @Transactional的传播行为和隔离级别;
- Spring @Transactional的工作原理;
- Spring @Transactional的注意事项;
- Spring @Transactional自我调用中的问题。
1、Spring @Transactional的配置
步骤一、在Spring配置文件中引入命名空间
1
2
3
4
5
6
7
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
步骤二、xml配置文件中,添加事务管理器bean配置
<!-- 事务管理器配置,单数据源事务 --> <bean id="pkgouTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="pkGouDataSource" /> </bean><!-- 使用annotation定义事务 --> <tx:annotation-driven transaction-manager="pkgouTransactionManager" />
步骤三、在使用事务的方法或者类上添加 @Transactional(“pkgouTransactionManager”)注解
2、 Spring @Transactional的传播行为和隔离级别
1> 事务注解方式: @Transactional
- 标注在类前:标示类中所有方法都进行事务处理
- 标注在接口、实现类的方法前:标示方法进行事务处理
2> 事务传播行为介绍:
3> 事务超时设置:
@Transactional(timeout=30) //默认是30秒
4> 事务隔离级别:
- 脏读 : 一个事务读取到另一事务未提交的更新数据
- 不可重复读 : 在同一事务中, 多次读取同一数据返回的结果有所不同, 换句话说, 后续读取可以读到另一事务已提交的更新数据。相反,”可重复读”在同一事务中多次读取数据时,能够保证所读数据一样,也就是后续读取不能读到另一事务已提交的更新数据
- 幻读 : 一个事务读到另一个事务已提交的insert数据
@Transactional的属性:
3、 Spring @Transactional的工作原理
- 自动提交
默认情况下,数据库处于自动提交模式。每一条语句处于一个单独的事务中,在这条语句执行完毕时,如果执行成功则隐式的提交事务,如果执行失败则隐式的回滚事务。
事务管理,是一组相关的操作处于一个事务之中,因此必须关闭数据库的自动提交模式。这点,Spring会在org/springframework/jdbc/datasource/DataSourceTransactionManager.java中将底层连接的自动提交特性设置为false。
1
2
3
4
5
6
7
8
9
10
11
12
// switch to manual commit if necessary。 this is very expensive in some jdbc drivers,
// so we don't want to do it unnecessarily (for example if we've explicitly
// configured the connection pool to set it already)。if (con。getautocommit())
{
txobject.setmustrestoreautocommit(true);
if (logger.isdebugenabled())
{
logger.debug("switching jdbc connection [" + con + "] to manual commit");
}
//首先将自动提交属性改为false
con.setautocommit(false);
}
- spring事务回滚规则
Spring事务管理器回滚一个事务的推荐方法是在当前事务的上下文内抛出异常。Spring事务管理器会捕捉任何未处理的异常,然后依据规则决定是否回滚抛出异常的事务。
默认配置下,Spring只有在抛出的异常为运行时unchecked异常时才回滚该事务,也就是抛出的异常为RuntimeException的子类(Errors也会导致事务回滚)。而抛出checked异常则不会导致事务回滚。
Spring也支持明确的配置在抛出哪些异常时回滚事务,包括checked异常。也可以明确定义哪些异常抛出时不回滚事务。
还可以编程性的通过setRollbackOnly()方法来指示一个事务必须回滚,在调用完setRollbackOnly()后你所能执行的唯一操作就是回滚。
在上面,我们使用了声明式事务来配置事务,使事务配置从service逻辑处理中解耦出来。但它还存在一些缺点:
1. 我们只针对方法名的特定进行拦截,但无法利用方法签名的其它信息定位,如修饰符、返回值、方法入参、异常类型等。如果我们需要为同名不同参的同载方法配置不同事务就会出问题了。
2. 事务属性的配置串虽然能包含较多信息,但配置较易出错。
针对这些问题,我们可以基于Schema,引入tx和aop的命名空间来改进我们的配置:
- 引入命名空间
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
- tx\aop核心配置
<!-- 配置事务属性 --><tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRES_NEW" /> <tx:method name="update*" propagation="REQUIRES_NEW" /> <tx:method name="delete*" propagation="REQUIRES_NEW" /> <tx:method name="*" read-only="true"/> </tx:attributes></tx:advice><!-- 配置事务切入点,以及把事务切入点和事务属性关联起来 --><aop:config proxy-target-class="true"> <aop:pointcut expression="execution(* com.yc.service.*.*(..))" id="ServicePointcut" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="ServicePointcut" /></aop:config>
这里需要特别注意的是,我们需要在标签中将proxy-target-class配置成true,否则会出现和上一篇文章相同的错误:我们定义的类无法转换成代理类
这里我们通过来配置我们的事务增强属性。在标签中,常见属性及其说明如下,其中,除了name属性是必选外,其他都是可选的:
- Spring 声明式事务中使用注解@Transactional的方式、原理及注意事项
- Spring声明式事务注解@Transactional
- spring丶基于@Transactional注解的事务配置,声明式事务管理的使用
- spring事务配置,声明式事务管理和基于@Transactional注解的使用
- spring事务配置,声明式事务管理和基于@Transactional注解的使用
- Spring事务配置,声明式事务管理和基于@Transactional注解的使用
- 基于@Transactional注解方式的spring声明式事务管理
- Spring声明式事务——全注解方式(@Transactional)
- [spring,mysql] spring使用注解式事务声明(@Transactional)无法回滚
- Spring @Transactional注解使用注意事项
- 在使用spring mvc时,我使用了@Service这样的注解, 发现使用注解@Transactional声明的事务不起作用
- 在使用spring mvc时,我使用了@Service这样的注解, 发现使用注解@Transactional声明的事务不起作用
- spring的事务注解@Transactional
- @transactional 事务注解注意事项
- Spring MVC @Transactional注解方式事务失效的解决办法
- Spring MVC @Transactional注解方式事务失效的解决办法
- Spring MVC @Transactional注解方式事务失效的解决办法
- Spring MVC @Transactional注解方式事务失效的解决办法
- 编译opencv库的注意事项
- 用Javascript写简单计算器
- 计蒜客第五场过后……
- sublime markdown 配色
- js基础篇(二)
- Spring 声明式事务中使用注解@Transactional的方式、原理及注意事项
- 第一次python笔记
- codeforces799E Aquarium decoration
- 标准通用标记语言(SGML)
- JavaScript闭包
- LabVIEW生成任意波形
- 如何将 ASP.Net Web API 在 IIS 服务器上托管
- 如何安装Linux系统
- long和int