SPRing对于数据库的事务管理,是通过事务管理器进行操作,以下为两大类配置方法:
一、基于xml配置文件:
<!-- 1,配置事务管理器(根据情况使用合适的事务管理器) --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 2,配置管理事务的通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 配置方法与事务的关系 --> <tx:attributes> <!-- 指定add,delete,update都开启事务 --> <tx:method name="save*"/> <tx:method name="delete*"/> <tx:method name="update*"/> <!-- 只读事务 --> <tx:method name="query*" read-only="true"/> </tx:attributes> </tx:advice> <!-- 3,配置AOP --> <aop:config> <!-- 切面 --> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.stephen..*Service*.*(..))"/> </aop:config>注意点:
1、配置了切面的切入点pointcut后,只是拦截了对应的方法,并没有做任何动作,需要再通知中加入tx:attribute 和 tx:method约定需要开启事务的方法;
2、在匹配的方法中,直接具有事务管理功能,无需再进行硬编码;
二、基于注解方式进行事务管理
<!-- 1,配置事务管理器(根据情况使用合适的事务管理器) --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 2,开启使用注解方式管理事务 --> <tx:annotation-driven transaction-manager="transactionManager"/>注意点:1、注解方式同样需要先配置事务管理器;
2、告知Spring容易,需要使用注解方式来进行事务管理;
3、在需要事务管理的方法或者类上使用@Transactional 注解修饰, 方法上的注解优先于类上的;
三、事务传播行为
一个业务方法中如果存在多个事务嵌套一起,默认情况下事务会同时作用,如果需要事务独立作用,例如日志事务,其他事务出错后,日志事务仍生效,则需要使用事务传播行为。
1、注解方式中@Trasactional的属性propagation,其中有
传播行为:定义关于客户端和被调用方法的事物边界
传播行为 | 意义 |
REQUIRED (默认值) | 业务方法需要在一个事务中运行。如果方法运行时,已经处在一个事务中,那么加入到该事务,否则为自己创建一个新的事务 |
NOT_SUPPORTED | 声明方法不需要事务。如果方法没有关联到一个事务,容器不会为它开启事务。如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行 |
REQUIRES_NEW | 属性表明不管是否存在事务,业务方法总会为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务会被挂起,新的事务会被创建,直到方法执行结束,新事务才算结束,原先的事务才会恢复执行 |
MANDATORY | 该属性指定业务方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果业务方法在没有事务的环境下调用,容器就会抛出例外。 |
SUPPORTS | 这一事务属性表明,如果业务方法在某个事务范围内被调用,则方法成为该事务的一部分。如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行 |
Never | 指定业务方法绝对不能在事务范围内执行。如果业务方法在某个事务中执行,容器会抛出例外,只有业务方法没有关联到任何事务,才能正常执行 |
NESTED | 如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按REQUIRED属性执行.它使用了一个单独的事务, 这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效 |
在日志方法中使用@Transactional(propagation = Propagation.REQUIRES_NEW) ,则可以完成,当其他事务回滚时,日志方法仍生效;
新闻热点
疑难解答