使用注解版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里的写的顺序进行执行

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 框架为我们提供的一种可以在代码中手动控制增强代码什么时候执行的方式。
注意: 通常情况下,环绕通知都是独立使用的

around环绕通知

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();}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/333212.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows系统下彻底卸载MySQL数据库

1.正常卸载MySQL数据库 2.将 C:/ProgramData 目录下的子目录 MySQL 删除 注意&#xff1a;目录 ProgramData 是隐藏目录&#xff0c;你正常情况下看不到&#xff0c;你可以在文件地址栏输入 C:/ProgramData 进入该目录下。

ibm收购red hat_IBM将收购Red Hat:面向Java的初衷

ibm收购red hatOracle公司近九年前完成了收购Sun Microsystems的过程。 那是当时的大新闻&#xff0c;今天也宣布了类似的大新闻&#xff1a; IBM和Red Hat已经同意IBM收购Red Hat 。 IBM主页面宣布“ IBM收购Red Hat”。 然后&#xff0c;它说&#xff1a;“这将改变一切。” …

Windows系统的MySQL目录结构

安装目录 安装 MySQL 时&#xff0c;如果我选择安装在 D:\develop\MySQL&#xff0c;那么你安装好之后点击文件夹 MySQL 可以看到如下内容&#xff1a; 目录 bin&#xff1a;存放二进制可执行文件 目录 data&#xff1a;存放数据库日志文件等 目录 include&#xff1a;C语言…

java监控数据库性能_Java:GraalVM数据库流性能

java监控数据库性能GraalVM是JVM块的新成员。 它是一个开源虚拟机&#xff0c;能够同时运行多种编程语言&#xff0c;例如Java&#xff0c;Rust和JavaScript。 GraalVM还具有一个新的内部代码优化器管道&#xff0c;与某些条件下的其他JVM相比&#xff0c;它可以显着提高性能。…

@Param注解注意事项(小的细节)

一、关于dao和UserDao.xml的参数问题 dao接口里是否有Param进行映射&#xff0c;和UserDao.xml的参数的书写格式有关系 多参数类型的时候&#xff0c;使用param 如果dao接口里写了Param&#xff08;“uid”&#xff09;&#xff0c;UserDao.xml的参数必须要写#{uid} 或者#{p…

jep122_JEP 181不兼容,嵌套类/ 2

jep122JEP 181是基于嵌套的访问控制https://openjdk.java.net/jeps/181 。 它是在Java 11中引入的&#xff0c;它故意引入了与先前版本的不兼容性。 这是一个很好的例子&#xff0c;与Java的早期版本兼容并不是刻板的规则&#xff0c;而是保持语言的一致性和稳定发展。 在本文中…

文档中快速输入日期时间的方法

文章目录word文档excel表格日期输入后固定不变日期输入后会根据系统变化的输入法快速输入日期时间&#xff08;推荐&#xff09;word文档 输入 ctrl;&#xff0c;就可以直接输入当前日期 输入 ctrlshift;&#xff0c;就可以直接输入当前时间 如果是输入当前日期和时间&#xf…

=空值返回空值_@ParameterizedTest在@CvsSource中具有空值

空值返回空值在JUnit 4中编写参数化测试非常麻烦。 JUnit 5对框架进行了一些有用的改进&#xff0c;并且使用不同的参数运行相同的测试比以前的版本要简单得多。 但是&#xff0c;在这样的参数中传递空值存在一个小问题。 在本文中&#xff0c;我将向您展示如何在JUnit 5中的P…

MySQL的配置文件_选项文件_参数文件

文章目录WindowsLinux使用命令 locate 查找含有关键词 my.cnf 的文件路径查看是否使用了指定目录下的 my.cnf 文件查看 MySQL 默认读取 my.cnf 文件路径启动时没有读取任何配置文件主要的配置参数类似于 Oracle 的参数文件&#xff0c;MySQL 的选项文件&#xff08;即配置文件&…

java url参数转换:_提示:通过URL激活并发送参数

java url参数转换:世界上最安全的密码是不存在的密码。 使用完全随机的密钥从等式中删除用户。 公平地说&#xff0c;这有一些缺点&#xff0c;并且密码仍然存在于某处&#xff08;在您的电话/电子邮件中&#xff09;&#xff0c;但通常这样效果很好... 诀窍很简单&#xff0c…

简单的vue入门案例

一、 简单入门Hello World案例 二、插值表达式 三、点击事件 四、按键事件 1.如果按下不是 0 - 9 则阻止事件执行 2.打印按下什么按键 五、鼠标事件 1.打印绝对坐标 2.打印相对坐标 3.鼠标mousemove 4. 阻止冒泡(阻止事件的传播) 六、事件修饰符 1.阻止跳转页面v-on:submit.…

javafx 调用java_Java,JavaFX的流畅设计风格进度栏

javafx 调用java按照承诺&#xff0c;刚刚发布的Java JavaFX主题JMetro版本4.6为进度栏带来了新样式。 进度栏有两种可能的状态&#xff1a;确定和不确定&#xff0c;新的JMetro版本针对这两种具有不同的样式。 在本文中&#xff0c;我还将详细介绍我在JMetro中遵守的一些API设…

vue基本用法

一、v-text与v-html.html v-html 可以解析标签&#xff0c;解析样式,v-text不能解析&#xff0c;只能原样输出 二、v-bind绑定参数 v-bind简写方式 <!-- 完整语法 --> <a v-bind:href"url">...</a> <!-- 缩写 --> <a :href"url&q…

类Unix系统下,vim各种模式之间的切换

文章目录普通命令模式插入模式&#xff08;编辑模式&#xff09;临时切换到普通命令模式可视模式&#xff08;文本选择模式&#xff09;底行命令模式&#xff08;EX 命令模式&#xff09;普通命令模式 vim 的默认模式就是普通命令模式&#xff0c; 使用 vim 打开文件就进入普通…

jdk12 switch_玩JDK 12的Switch表达式

jdk12 switch在博客文章“操作中的JDK语言功能预览&#xff1a;切换表达式 ”中&#xff0c;我讨论了JEP 325 [“切换表达式&#xff08; 预览 &#xff09;”&#xff09;如何作为指定的“ 预览语言功能 ”的早期应用&#xff0c;如JEP 12所述。预览语言和VM功能”]。 JEP 325…

VueJS生命周期

一、生命周期 vue在生命周期中有这些状态&#xff0c; beforeCreate,created,beforeMount,mounted,beforeUpdate,updated,beforeDestroy,destroyed。Vue 在实例化的过程中&#xff0c;会调用这些生命周期的钩子&#xff0c;给我们提供了执行自定义逻辑的机会。 vue对象初始化过…

Linux的命令之 man -- 查看帮助文档

文章目录浏览文本内容的快捷键向前滚屏向后滚屏跳跃搜索使用这个命令可以查看任何命令的在线帮助文件&#xff0c;例如&#xff0c;查看命令 find 的在线帮助文档&#xff1a; [roothtlwk0001host ~]# man find打开命令的帮助文档后&#xff0c;可以使用鼠标滚轮上下滚动来浏览…

jdk8切换成jdk6_运行中的JDK语言功能预览:切换表达式

jdk8切换成jdk6JEP 12 [“预览语言和VM功能”]在其主页上描述如下&#xff1a; 预览语言或VM功能是Java SE平台的一项新功能&#xff0c;该功能已完全指定&#xff0c;完全实现但不是永久性的。 JDK功能发布中提供了该功能&#xff0c;以根据实际使用情况激发开发人员反馈。 这…

VueJS ajax综合案例

一、目录结构和注意事项 1.目录结构 2.注意事项 &#xff08;1&#xff09;data.html里面的Vue &#xff08;2&#xff09;箭头函数 二、引入依赖 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0…