使用注解版AOP解决事务问题
一、注解版和xml版的区别
1、 通知的四种常用类型
(1)aop:before
作用: 用于配置前置通知。指定增强的方法在切入点方法之前执行 属性: method:用于指定通知类中的增强方法名称 ponitcut-ref:用于指定切入点的表达式的引用 poinitcut:用于指定切入点表达式 执行时间点: 切入点方法执行之前执行
<aop:before method=“beginPrintLog” pointcut-ref=“pt1”/>
(2)aop:after-returning
作用: 用于配置后置通知 属性: method:指定通知中方法的名称。 pointct:定义切入点表达式 pointcut-ref:指定切入点表达式的引用 执行时间点: 切入点方法正常执行之后。它和异常通知只能有一个执行
<aop:after-returning method=“afterReturningPrintLog” pointcut-ref=“pt1”/>
(3)aop:after-throwing
作用: 用于配置异常通知 属性: method:指定通知中方法的名称。 pointct:定义切入点表达式 pointcut-ref:指定切入点表达式的引用 执行时间点: 切入点方法执行产生异常后执行。它和后置通知只能执行一个
<aop:after-throwing method=“afterThrowingPringLog” pointcut-ref=“pt1”/>
(4) aop:after
作用: 用于配置最终通知 属性: method:指定通知中方法的名称。 pointct:定义切入点表达式 pointcut-ref:指定切入点表达式的引用 执行时间点: 无论切入点方法执行时是否有异常,它都会在其后面执行。
<aop:after method=“afterPringLog” pointcut-ref=“pt1”/>
2、四种常用类型通知的执行顺序
(1)xml的织入顺序是按照xml里的写的顺序进行执行
(2)注解版织入的顺序则和运行时出现的情况进行分两种分析
Ⅰ.正常运行
注解通知正常执行时:
正常执行时会先执行 @before 然后再执行 @After 最后执行@ After-returning
所以正常情况下要在 TransactionManager里的标注事务的状态时对应的通知
如果一开始让@After对应为release()则事务将提前释放资源,造成无法提交,所以要把@After对应为Commit(),这样就可以先提交再释放资源
Ⅱ.抛出异常时 After 的执行顺序
如果一开始让@After对应为release()则事务将提前释放资源,造成无法提交,所以要把@After对应为rollBack(),这样就可以先抛异常再释放资源
1.需要改动是文件
1.applicationContext.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><!--开启注解扫描--><context:component-scan base-package="com.william"></context:component-scan><!--创建QueryRunner--><bean id="QueryRunner" class="org.apache.commons.dbutils.QueryRunner"></bean><!--创建dataSource--><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.driverClass}"></property><property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property><property name="user" value="${jdbc.user}"></property><property name="password" value="${jdbc.password}"></property></bean><!--引入属性文件--><context:property-placeholder location="classpath:db.properties"></context:property-placeholder><aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</beans>
2.在TransactionManager进行注解
代码:使用的是四种的执行顺序,没使用around环绕通知
执行顺序按照
package com.william.utils;import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.sql.SQLException;/*** @author :lijunxuan* @date :Created in 2019/5/27 16:50* @description :* @version: 1.0*/
@Component
@Aspect
public class TransactionManager {@Pointcut("execution(* com.william.service.Impl.*.*(..))")public void pc(){}@AutowiredConnectionUtils connectionUtils;@Before("pc()")public void beganTransaction(){try {connectionUtils.getThreadConnection().setAutoCommit(false);System.out.println(" beganTransaction "+connectionUtils.getThreadConnection());} catch (SQLException e) {e.printStackTrace();}}@After("pc()")public void Commit(){try {System.out.println(" Commit "+connectionUtils.getThreadConnection());connectionUtils.getThreadConnection().commit();} catch (SQLException e) {e.printStackTrace();}}@AfterThrowing("pc()")public void rollBack(){try {System.out.println(" rollBack "+connectionUtils.getThreadConnection());connectionUtils.getThreadConnection().rollback();} catch (SQLException e) {e.printStackTrace();}}@AfterReturning("pc()")public void release(){try {System.out.println(" release "+connectionUtils.getThreadConnection());connectionUtils.getThreadConnection().setAutoCommit(true);connectionUtils.getThreadConnection().close();connectionUtils.remove();} catch (SQLException e) {e.printStackTrace();}}
}
二、使用around环绕通知可以解决上面的问题
配置方式:
<aop:config> <aop:pointcut expression="execution(* com.william.service.impl.*.*(..))" id="pt1"/> <aop:aspect id="txAdvice" ref="txManager"> <!-- 配置环绕通知 --> <aop:around method="transactionAround" pointcut-ref="pt1"/> </aop:aspect> </aop:config>
aop:around: 作用: 用于配置环绕通知
属性:
method:指定通知中方法的名称。
pointct:定义切入点表达式
pointcut-ref:指定切入点表达式的引用
说明: 它是 spring 框架为我们提供的一种可以在代码中手动控制增强代码什么时候执行的方式。
注意: 通常情况下,环绕通知都是独立使用的
package com.william.utils;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.sql.SQLException;/*** @author :lijunxuan* @date :Created in 2019/5/27 16:50* @description :* @version: 1.0*/
@Component
@Aspect
public class TransactionManager {@Pointcut("execution(* com.william.service.impl.*.*(..))")public void pc(){}@Around("pc()")public Object around(ProceedingJoinPoint joinPoint){try {beginTransaction();//执行原始的方法Object result = joinPoint.proceed();commit();return result;} catch (Throwable throwable) {throwable.printStackTrace();rollback();} finally {release();}return null;}@AutowiredConnectionUtils connectionUtils;public void beginTransaction(){try {connectionUtils.getThreadConnection().setAutoCommit(false);} catch (SQLException e) {e.printStackTrace();}}public void commit(){try {connectionUtils.getThreadConnection().commit();} catch (SQLException e) {e.printStackTrace();}}public void rollback(){try {connectionUtils.getThreadConnection().rollback();} catch (SQLException e) {e.printStackTrace();}}public void release(){try {connectionUtils.getThreadConnection().setAutoCommit(true);connectionUtils.getThreadConnection().close();connectionUtils.remove();} catch (SQLException e) {e.printStackTrace();}}
}
使用注解版AOP解决事务问题相关推荐
- 使用aop解决事务问题(xml版)
一.引入依赖 pom.xml代码: <?xml version="1.0" encoding="UTF-8"?> <project xmlns ...
- 基于注解的AOP实现事务控制及问题分析
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...
- 通过AOP控制事务的案例
1.xml配置版 执行以下sql语句 create table account(id int primary key auto_increment,name varchar(40),money flo ...
- 基于Spring AOP的统一响应体的实现(注解版)
基于Spring AOP的统一响应体的实现(注解版) 一.前言 在上一篇系列中 我们 统一参数校验,统一结果响应,统一异常处理,统一错误处理,统一日志记录,统一生成api文档, 对于统一数据响应返回规 ...
- Spring中解决事务以及异步注解失效
Spring中解决事务以及异步注解失效 一.重现@Transaction失效的场景 有如下业务场景,新增订单后,自动发送短信,下面的代码在同一个类中: @Transaction public void ...
- 注解mysql事物管理_Spring事务管理-注解版
Spring事务管理-注解版 一.拷贝必要的jar包到工程的lib目录 二.创建spring的配置文件并导入约束 xmlns:xsi="http://www.w3.org/2001/XMLS ...
- spring事务管理-注解配置aop事务(重点)
导包,导入新的约束,通知都不用配了,这两个是一样的,导包这一步,新的约束,tx这些都是一样的,第三步开始不同,这个注解配置大概一分钟就讲完了,第三步咱们可以开启注解,管理事务,那这块的话,咱们的配置文 ...
- Spring→事务、隔离级别、事务传播行为、编程式事务控制、XML配置声明式事务(原始方式)、XML配置声明式事务(基于tx/aop)、@注解配置声明式事务、优势总结
事务 Spring事务管理 不考虑隔离引发问题 隔离级别 事务传播行为 演示环境搭建 编程式事务控制 XML配置声明式事务(原始方式) XML配置声明式事务(基于tx/aop) @注解配置声明式事务 ...
- Spring —— 基于注解的Aop在同一类下产生嵌套时切面不生效问题产生原因及解决
一.背景介绍 由于程序中大量方法需要监控执行耗时,因此写了基于注解的Aop类来减少重复代码,主要作用是通过环绕通知在方法执行前后进行耗时计算,最后输出到日志/监控. 相关代码如下: // 注解 @Re ...
最新文章
- IDEA中PlantUML的使用
- saxon java_如何将Saxon设置为Java中的Xslt处理器?
- JSON 之 SuperObject(6): 方法
- php m grep event,php-如何杀死与30分钟以上的grep匹配的进程?
- SQL Server 2005 Service Broker 初探 [摘抄]
- FileStream:The process cannot access the file because it is being used by another process
- mysql_视图与变量
- 一分钟学会神经网络3——图解深度学习原理(有这篇博客就够了)
- 线上展示3D可视化电子沙盘管理系统
- 【DB宝41】监控利器PMM的使用--监控MySQL、PG、MongoDB、ProxySQL等
- 百度网盘搜索工具汇总
- 【视觉高级篇】23 # 如何模拟光照让3D场景更逼真?(上)
- 国标28181:什么是RTSP协议
- yandex 浏览器 linux,细致比拼 六大Android手机浏览器实测
- 防坑指南: 杨工告诉你免联考国际硕士到底是个什么梗?
- python三国演义人物 统计分析_Python统计三国演义主要人物出场次数
- 【JAVA今法修真】 第三章 关系非关系 redis法器
- 常见的进制和进位规则
- 利用卷积神经网络对DWI的急性缺血性病变进行全自动分割
- GANs: 学习生成一维正态分布
热门文章
- activiti 变量_如何在Activiti中使用瞬态变量
- java的默认值规则_Java 8:默认方法解析规则
- jpa 忽略bean_在WildFly上将JPA和CDI Bean与骆驼一起使用
- activemq网络桥接_ActiveMQ –经纪人网络解释–第3部分
- maven使用testng_使用Maven Failsafe和TestNG分别运行单元测试和集成测试
- 将原生SQL功能Hibernate到您的Spring Data Repository中
- AssertJ的SoftAssertions –我们需要它们吗?
- Java和甜蜜的科学
- Java验证(javafx)
- Java / JEE中的有效日志记录–映射的诊断上下文