Spring_声明式事务
编程式事务:
由程序员编写事务控制代码,例如:OpenSessionInView。
声明式事务:
由框架提供的,程序员只需要声明出哪些方法要进行事务控制和如何进行事务控制。
一、配置
1、准备要进行事务管理的数据库对象
<!--DataSource对象--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:53306/lurenjia_web"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> </bean>
2、声明一个事务管理器
<!--事务管理器--> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--需要一个DataSource对象来知道对哪个数据库进行关联,可以使用自动注入--> <property name="dataSource" ref="dataSource"></property> </bean>
3、配置声明式事务
<!--配置声明式事务--> <tx:advice id="txAdvice" transaction-manager="txManager"> <!--具体哪些方法需要有事务控制--> <tx:attributes> <!--REQUIRED:默认事务传播行为--> <tx:method name="ins*" propagation="REQUIRED"/> <tx:method name="del*"/> <tx:method name="upd*"/> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <!--声明式事务是基于aop实现的,所以需要配置aop--> <aop:config> <!--配置切点范围,需要包括需要有事务控制的方法--> <aop:pointcut id="point_tx" expression="execution(* com.lurenjia.service.impl.*.*(..))"/> <!--事务通知配置--> <aop:advisor advice-ref="txAdvice" pointcut-ref="point_tx"></aop:advisor> </aop:config>
二、属性说明
(一)、propagation属性(事务传播行为)
控制事务传播行为,即多个含有事务控制的方法之间相互调用的时候,对于事务关系的设置。
取值:
required(默认值),如果当前有事务,则在事务中执行,如果没有,则创建一个。
supports,如果当前有事务,则在事务中执行,如果没有,则在非事务状态下执行。
mandatory,如果当前有事务,则在事务中执行,如果没有,则报错。
requires_new,如果当前没有事务,则创建一个事务,如果有,则把当前事务挂起。(必须在自己的事务中执行)
not_supported,如果当前没有事务,则正常执行,如果有,则把事务挂起。(必须在非事务中执行)
never,如果当前没有事务,则正常执行,如果有,则报错。
nested,如果当前没有事务,则创建一个事务,如果有事务,则创建一个嵌套事务。
(二)、read-only属性
设置方法是否为只读事务。
取值:
true,告知数据库此事务为只读事务,则不会对此事务加锁,则效率高。(查询)
false(默认),非只读事务,需要提交的事务。(增删改)
(三)、isolation属性(隔离级别)
设置事务的隔离级别,主要用于解决:脏读、不可重复读、幻读
取值:
default,默认值,由数据库自动判断使用什么隔离级别
read_uncommitted,可以读取到其他事务未提交的数据。(会出现脏读、不可重复读、幻读,效率高)
read_committed,只能读取到其他事务已经提交了的数据。(可以避免脏读)
repeatable_read,读取的数据会被加锁,其它事务不可修改(可以避免脏读,不可重复读)
serializable,对读取的表添加锁,其它事务不可操作。(不会出现脏读、不可重复读、幻读,效率低)
(四)、rollback-for属性(异常回滚)
设置出现什么异常的时候发生回滚
取值:
异常类的全限定路径(包名.类名)
问题:
虽然默认值为java.lang.Exception,但是可能出现手动抛出异常不回滚的情况(throws new Exception())。
解决:
给点此属性值。
(五)、no-rollback-for属性(异常不回滚)
设置出现什么异常的时候事务不发生回滚
取值:
异常类的全限定路径(包名.类名)
使用场景:
抛出异常是为了阻止程序继续运行,类似于return。