spring事务管理的两种方式注意细节
来源:互联网 发布:关键词排名优化外包 编辑:程序博客网 时间:2024/05/22 00:36
在这里我们只是说spring和myBatis的事务使用方式
目前事务分为声明式事务和编程事务,编程式事务就不做详细介绍了
今天说一下声明式事务,常用的声明式事务方式分为:aspectJ和注解
首先说一下aspectJ的配置说明
<!-- 定义事务 -->
<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceWeb"/>
</bean>
<!-- 拦截器方式配置事物-->
<tx:adviceid="transactionAdvice"transaction-manager="transactionManager">
<tx:attributes>
<tx:methodname="*" propagation="REQUIRED" read-only="false"
rollback-for="Throwable" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="transactionPointcut"
expression="execution(* com.eventown.btravel.service..*.*(..))"/>
<aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice"/>
</aop:config>
说一下上面的代码,首先我们需要一个事务管理器来对数据源做事务的控制,然后我们需要配置事务建议和事务的传播特性。什么叫传播特性,这里有必要详细解释一下:
事务的传播特性就是指多个事务方法调用时候,事务如何在这些方法间进行传递
Spring提供了7种事务的传播特性分别是:
特性名称
特性描述
PROPAGATION_REQUIRED
如果存在一个事务,则支持当前事务。如果没有事务则开启,通常做为默认的特性
PROPAGATION_SUPPORTS
如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
PROPAGATION_MANDATORY
如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常
PROPAGATION_REQUIRES_NEW
总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起
PROPAGATION_NOT_SUPPORTED
总是非事务地执行,并挂起任何存在的事务。
PROPAGATION_NEVER
总是非事务地执行,如果存在一个活动事务,则抛出异常
PROPAGATION_NESTED
如果一个活动的事务存在,则运行在一个嵌套的事务中.如果没有活动事务,
在这里我们可以配置多种不同方法的事务传播行为
<tx:method name="*"propagation="REQUIRED" read-only="false"
rollback-for="Throwable" />
说明一下这里的参数
参数名称
注释
name
匹配当前方法名称的所有方法,可以使用*通配符,save*,代表以save开头的所有方法
propagation
指示当前方法所使用的事务传播机制
isolation
事务的隔离级别,一般使用默认值就行(DEFAULT)
read-only
事务是否只读, 表示此方法只能用于查询
rollback-for
触发回滚的异常,包含当前类以及子类(可以不配置)
no-rollback-for
不触发回滚的异常类(可以不配置)
之后我们需要配置aop拦截设置
在aop:config中我们需要指定我们的切割点和对应事务配置的建议(advice)
<aop:pointcut id="transactionPointcut"
expression="execution(。。。。)"/>
这个切割点我们需要指代一个使用aspectJ的表达式来指定某些返回值的某些包下的某些包的某些方法具体指定到方法级为止
execution(* com.ning.service..*.*(..))
第一个*号是指返回值类型,当然在返回值类型之前我们也可以指代此方法是public类型的
后面跟着是我们的包名,以上为例,包名后面如果跟着两个点,则代表service包和子包的所有类全都在事务的管理范围之中,当然如果只有一个点只表示service包下的所有类,子包下的类不在事务管理范围
后面的第二个*代表的是类名,代表了所有的类
后面*(..)代表了类下的所有方法,里面的两个点代表了所有的参数
总体来说完整的写法就是
execution(* com.ning.service..*.*(..))
代表的意思是:com.ning.service包和子包下的所有方法都是切割点
这种写法也是基本所有项目都会使用的,如果有特殊要求的还是建议多看看aspectJ的表达式,来写出精确的表达式
接下来就是需要将我们写的切割点和我们的事务建议(advice)进行组合
aop:advisor
这个标签有两个属性pointcut-ref和advice-ref
pointcut-ref指的是切割点
advice-ref是事务的建议(advice)
到此位置就完成了事务的第一种配置
下面我们来说一下关于注解的配置
注解的配置需要我们在配置文件中配置的内容就比较少
<bean id="txManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 配置TransactionManager -->
<constructor-arg name="dataSource"ref="dataSourceWeb"/>
</bean>
<!-- 开启事务注解 -->
<tx:annotation-driven transaction-manager="txManager"/>
这里首先为数据源定义一个事务管理器,使用这个事务管理器来管理我们的注解事务
之后我们就对我们的service类添加注解来提供事务
属性
描述
value
可选的限定描述符,指定使用的事务管理器
propagation
可选的事务传播行为设置
isolation
可选的事务隔离级别设置
readOnly
读写或只读事务,默认读写
timeout
事务超时时间设置
rollbackFor
导致事务回滚的异常类数组
rollbackForClassName
导致事务回滚的异常类名字数组
noRollbackFor
不会导致事务回滚的异常类数组
noRollbackForClassName
不会导致事务回滚的异常类名字数组
@Transactional
public class UserService{
@Transactional
publicvoid save(){}
publiUser queryAndUpdate(){
//TODO
update();
}
@Transactional
publicvoid update(){}
}
@Transactional 可以写在类名上,也可以只写在方法上,
但是需要注意的是,当同一个类中,如果该类没有添加注解,仅仅只是在部分方法上添加了事务注解,那么一个没有事务的方法调用了一个有事务的方法,那么该事务不会生效
这是因为注解方式的实现方式导致的,所以我们尽量对需要有事务的方法都放在一个类中,没有事务的方法放在另外一个类中,避免这种问题的出现
- spring事务管理的两种方式注意细节
- Spring事务管理的两种方式
- spring事务管理的两种方式
- spring声明式事务管理的两种方式
- Spring嵌套事务的两种事务管理配置方式
- 事务管理两种方式
- Spring事务管理的两种模式
- spring的事务管理方式!
- spring 事务管理的方式
- Spring声明式事务管理的两种方式(XML和Annotation)
- Spring事务管理的五种配置方式
- Spring的五种事务管理方式
- spring中事务管理的几种方式
- Spring事务管理的五种方式
- Spring事务管理的三种方式
- Spring事务管理的三种方式
- Spring事务管理的三种方式
- Spring事务管理的5种配置方式
- linux系统下搭建本地owncloud网盘
- Java基础
- 【bzoj1116】 [POI2008]CLO
- shell脚本实现Linux ip的配置(增删改查)以及相关信息查看
- log4j.properties配置文件详解
- spring事务管理的两种方式注意细节
- Linux下" >/dev/null 2>&1 "相关知识说明(来自sunrier)
- 数组、集合、泛型
- 第十一天学习java内库
- SurfaceView 闪屏 黑线问题解决
- Sting、StringBuffer和StringBuilder的区别
- 【bzoj2430】 [Poi2003]Chocolate
- web.xml文件详解
- 批量操作资源或控件