声明式事务

通知声明式管理事务

	<!-- 1. 配置事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

	<!-- 2. 配置事务属性 -->
	<!-- <tx:advice>元素声明事务通知 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 根据方法名指定事务的属性 -->
			<tx:method name="*"/>
			<!-- propagation配置事务传播行为 -->
			<tx:method name="purchase" propagation="REQUIRES_NEW"/>
			<!-- isolation配置事务的隔离级别 -->
			<tx:method name="update*" isolation="SERIALIZABLE"/>
			<!-- rollback-for配置事务遇到异常必须回滚,no-rollback-for配置事务遇到异常必须不能回滚 -->
			<tx:method name="add*" rollback-for="java.io.IOException" no-rollback-for="exception.BookException"/>
			<!-- read-only配置事务只读属性 -->
			<tx:method name="find*" read-only="true"/>
			<!-- timeout配置事务的超时属性 -->
			<tx:method name="get*" timeout="3"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 3. 配置事务切入点, 以及把事务切入点和事务属性关联起来 -->
	<aop:config>
		<!-- “*”表示类或者方法。“..”表示包、子孙包下的所有类(service包下所有类)
		    “..”出现在类名中时,后面必须跟“*”,表示包、子孙包下的所有类
		    set*(..):表示匹配所有”set”开头的方法 -->
		<aop:pointcut id="txPointCut" expression="execution(* com.service..*.*(..))"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>	
	</aop:config>

@Transactional 注解声明式地管理事务

	<!-- 配置事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>


	<!-- 启用事务注解 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>


	//1.使用 propagation 指定事务的传播行为,默认取值为 REQUIRED, 即使用调用方法的事务
	//2.使用 isolation 指定事务的隔离级别, 最常用的取值为 READ_COMMITTED
	//3.默认情况下 Spring 的声明式事务对所有的运行时异常进行回滚. 也可以通过对应的属性进行设置. 通常情况下去默认值即可. 
	//4.使用 readOnly 指定事务是否为只读. 表示这个事务只读取数据但不更新数据, 
        这样可以帮助数据库引擎优化事务. 若真的事一个只读取数据库值的方法, 应设置 readOnly=true
	//5.使用 timeout 指定强制回滚之前事务可以占用的时间.
	@Transactional(propagation=Propagation.REQUIRES_NEW,
			isolation=Isolation.READ_COMMITTED,
			noRollbackFor={UserAccountException.class},
			rollbackFor = IOException.class,
			readOnly=false,
			timeout=3)
	public void purchase(String username, String age) {}

事务失效

方法中调用this本身的方法,即使在this的方法标明事务注解,但是事务注解会失效


@Transactional
public void purchase(String username, String age) {
    this.update(username, age);
}


解决

<!-- 开启aspectj代理,并暴露aop代理到ThreadLocal -->
<aop:aspectj-autoproxy expose-proxy="true"/>

@Transactional
public void purchase(String username, String isbn) {
	((ServiceImpl)AopContext.currentProxy()).update(username, age);
}

参考

https://blog.csdn.net/jiadajing267/article/details/81056057

原文地址:https://www.cnblogs.com/loveer/p/11471186.html