spring 注解事务
来源:互联网 发布:网络教育和电大区别 编辑:程序博客网 时间:2024/06/05 15:08
1.编程式事务管理
spring 编程式事务就是自己手动管理事务,spring 提供了 TransactionTemplate 这个类来手动管理事务的方式,使用如下 spring xml 配置
<!-- jdbc事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource"> <ref local="dataSource" /> </property> </bean> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager"> <ref local="transactionManager" /> </property> <!--ISOLATION_DEFAULT 表示由使用的数据库决定 --> <property name="isolationLevelName" value="ISOLATION_DEFAULT"/> <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/> <!-- <property name="timeout" value="30"/> --> </bean>TransactionTemplate 编程式事务java 使用public class SimpleService implements Service { //注解进来 @autowrite private final TransactionTemplate transactionTemplate; public Object someServiceMethod() { teturn transactionTemplate.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { try { updateOperation1(); updateOperation2(); } catch (SomeBusinessExeption ex) { status.setRollbackOnly(); //回滚 } } }); }}
当然你也可以使用 PlatformTransactionManager 类,来手动管理事务,不同的是,java代码要写的比 transactionTemplate 多点,需要自己手动提交,手动回滚事务。
而 transactionTemplate 只关心是不是要回滚。其实transactionTemplate 内部实现就是用 PlatformTransactionManager 来实现的,2种方法是一样的,按个人爱好来选择
2.声明式事务管理
Spring Framework的声明式事务管理是建立在Spring的面向切面编程(aspect-oriented programming, AOP)上的.简单来说就是通过aop 方式来管理事务常,不需要手动提交,回滚操作。这种方式对应用代码的影响最小, 并且最符合一个非侵入型轻量级容器的理想.
2.1 基于xml aop 配置方式
一种是 aop 风格的配置,当然还有其他的变种方式,即不使用tx,aop 标签,实际上是一样的,标签最终也是要解析成bean的
基于aop 风格 xml 配置
<!-- 配置事务传播特性 --> <tx:advice id="TestAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="del*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="find*" propagation="REQUIRED"/> <tx:method name="get*" propagation="REQUIRED"/> <tx:method name="apply*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- 配置参与事务的类 --> <aop:config> <!-- com.test.testAda.test.model.service 这个包下面的所有方法都被切入了事务--> <aop:pointcut id="allTestServiceMethod" expression="execution(* com.test.testAda.test.model.service.*.*(..))"/> <aop:advisor pointcut-ref="allTestServiceMethod" advice-ref="TestAdvice" /></aop:config><!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /></bean>
<tx:advice/>
标签默认的设置是:
- 传播行为设置是
REQUIRED.
- 隔离等级是
DEFAULT.
- 事务是可读可写.
- 事务超时是使用系统底层组件的默认值, 在不支持超时的时候没有超时.
- 任何的
RuntimeException
均触发回滚, 并且检查的Exception
不会回滚
你可以修改默认的设置; <tx:advice/>
和<tx:attributes/>
标签所需要的<tx:method/>
标签的属性都整理在下面了:
<tx:method/> 标签设置
name
是
事务属性所关联的方法名称(可能不唯一). 通配符(*)可以用于表示一组相同的方法; 例如, get*
, handle*
,on*Event
, 等等.
propagation
不是
REQUIRED
事务传播行为.
isolation
不是
DEFAULT
事务隔离等级.
timeout
不是
-1
事务超时的值(以秒为单位).
read-only
不是
false
事务是不是只读的?
rollback-for
不是
会触发回滚的Exception(可能不唯一)
; 使用逗号分隔. 例如,com.foo.MyBusinessException,ServletException.
no-rollback-for
不是
不会触发回滚的Exception(可能不唯一)
; 使用逗号分隔. 例如,com.foo.MyBusinessException,ServletException.
2.2基于注解的 @Transactional 配置
spring 注解事务
<!-- 使使用注解配置的事务行为生效 ,注解生效的前提请确保spring 能扫描到 @Transactional--><tx:annotation-driven transaction-manager="txManager"/><!-- 仍然需要一个PlatformTransactionManager --><bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- (这个需要的对象是在其他地方定义的) --> <property name="dataSource" ref="dataSource"/></bean>
代码中注解事务的调用,类上注解和方法上注解
@Transactional(readOnly = true)public class DefaultFooService implements FooService { public Foo getFoo(String fooName) { // do something } // 该方法的设置更优先 @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) public void updateFoo(Foo foo) { // do something }}
@Transactional 的属性
value
String
指定事务管理器使用的可选限定符.
propagation
enum: Propagation
指定传播属性设置.
isolation
enum: Isolation
指定隔离等级.
readOnly
boolean
设置事务是可读可写还是只读
timeout
int (用秒作为粒度)
事务超时.
rollbackFor
Class
对象数组, 必须是继承自Throwable.
的
指定 必定会触发回滚的类的数组.
rollbackForClassName
类名的数组. 类必须是继承自Throwable.
的
指定 必定会触发回滚的异常类的数组.
noRollbackFor
Class
对象的数组, 这些类必须是继承自Throwable.
的
指定 必定不会触发回滚的类的数组.
noRollbackForClassName
类的字符串数组, 这些类都必须继承自Throwable.
指定 必定不会触发回滚的异常类的数组.
@Transactional使用注意
方法可见性和@Transactional
当使用代理时, 你应该只给public可见性的方法添加@Transactional
注解. 如果你给protected, private或者包访问 的方法添加了@Transactional
注解, 不会产生错误, 但是添加了注解的方法并没有真正的配置了事务. 如果你需要给非公开的方法添加注解 可以参考AspectJ
在代理模式下(默认值), 只有来自外部方法的调用才会被代理拦截. 这意味着自我调用, 在效果上是, 目标对象的一个方法调用了目标对象的另一个 方法, 不会导致产生运行期的事务, 即使被调用的方法被@Transactional
标记了.
以下是无效的事务注解
public class DefaultFooService{ public Foo getFoo(String fooName) { updateFoo(); } // 该方法的设置更优先 @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) public void updateFoo() { // do something } public void main(String[] args){ DefaultFooService d=new DefaultFooService(); d.getFoo("a"); //间接调用(没有直接调用事务注解的那个方法)这样事务不生效的 }}
3.spring 事务传播行为
事务传播行为类型
说明
PROPAGATION_REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是 最常见的选择。
PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION_REQUIRED 类似的操作。
4.数据库事务隔离等级
数据库事务的隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题
脏读(Dirty Read)
脏读意味着一个事务读取了另一个事务未提交的数据,而这个数据是有可能回滚
不可重复读(Unrepeatable Read)
不可重复读意味着,在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。这是由于查询时系统中其他事务修改的提交而引起的。
例如:事务B中对某个查询执行两次,当第一次执行完时,事务A对其数据进行了修改。事务B中再次查询时,数据发生了改变
幻读(phantom read)
幻读,是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样.
- spring事务注解
- spring事务注解
- spring 事务注解
- Spring 事务注解
- Spring 注解事务说明
- Spring+Hibernate注解事务
- spring 注解事务
- spring事务注解
- spring添加注解事务
- spring注解事务
- Spring 事务注解
- Spring 事务注解
- spring 事务注解@Transactional
- spring 事务注解
- Spring 注解事务支持
- spring事务注解
- spring 事务注解
- Spring事务注解
- 面试小谈
- 除法运算、商、余数与取模
- 如何获取当前应用app所在的进程id和进程名称
- 非常好的Oracle基础教程
- [OpenStack]架构和基本概念
- spring 注解事务
- oralce游标详解
- 唐&杰出产品经理书 v1.0
- Java 对字符串进行MD5加密
- hdu3488(费用流)
- ios启动图片的延时
- 冰点文库----拒绝百度文库会员,高速下载文章
- butterknife 在eclipse的配置
- View controller-based status bar appearance