当前位置: 首页 > news >正文

手写@EnableTransactionalManagement

  • 定义一个注解,用于标注于方法上,标志着此方法是一个事务方法。
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTransaction {}
  • 定义一个开启事务功能的注解
@Component
@Import(TransActionBeanPostProcessor.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableTransactionalManagement {
}
  • BeanPostProcessor Bean的后置处理器,拦截每一个创建后的对象,这里拦截的是Bean的方法上标注了MyTransaction 注解的对象,为其创建代理对象。
/**对象事务处理器*/
public class TransActionBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {//判断bean的类或者方法上是否标注了事务注解@MyTransactionMyTransaction annotation = AnnotationUtils.findAnnotation(bean.getClass(), MyTransaction.class);boolean isTxProxy = false;if (annotation == null){//从方法上寻找Method[] methods = bean.getClass().getMethods();for (Method method : methods) {annotation = AnnotationUtils.findAnnotation(method, MyTransaction.class);if (annotation != null){isTxProxy = true;break;}}}if (isTxProxy){//为Bean创建代理对象bean = TransactionProxyUtil.getTxProxyObject(bean, transactionManagement());}return bean;}//给容器中注入事务管理器@Beanpublic PlatformTransactionManagement transactionManagement(){return new PlatformTransactionManagement();}}
  • JdbcTransactionStatus 定义一个事务的状态信息
public class JdbcTransactionStatus implements TransactionStatus{//private DataSource dataSource;private Connection connection;@Overridepublic void start() {//connection.setAutoCommit(false);System.out.println("connection.setAutoCommit(false); 开启事务");}@Overridepublic void commit() {//事务提交//connection.commit();System.out.println("事务提交了...");}@Overridepublic void rollback() {try {//事务回滚//connection.rollback();System.out.println("事务回滚了...");} catch (Exception throwables) {throwables.printStackTrace();}}@Overridepublic void close() {//connection.close();System.out.println("事务连接关闭了...");}
}
  • PlatformTransactionManagement 定义平台事务管理器,这个事务管理器主要管理DataSource数据源,在开启事务之前将Connection和当前线程绑定。
public class PlatformTransactionManagement implements TransactionManagement{@Overridepublic TransactionStatus getTransaction() {return new JdbcTransactionStatus();}@Overridepublic void commit(TransactionStatus status) {status.commit();}@Overridepublic void rollback(TransactionStatus status) {status.rollback();}@Overridepublic void close(TransactionStatus status) {status.close();}}
/**事务管理器*/
public interface TransactionManagement {//获取一个事务TransactionStatus getTransaction();//提交事务void commit(TransactionStatus status);//回滚事务void rollback(TransactionStatus status);//关闭连接void close(TransactionStatus transaction);
}
/**事务状态定义*/
public interface TransactionStatus {void start();//提交void commit();//回滚void rollback();//关闭连接void close();
}
  • 定义事务代理逻辑,创建代理对象,栏目目标方法,反射执行真正的方法,这里使用的是JDK的动态代理实现的。
public class TransactionProxyUtil {public static Object getTxProxyObject(Object source,TransactionManagement transactionManagement){Object proxyInstance = Proxy.newProxyInstance(source.getClass().getClassLoader(), source.getClass().getInterfaces(),new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//将方法替换为实现类中的方法,否则获取不到实现类方法上标注的注解String name = method.getName();Class<?>[] parameterTypes = method.getParameterTypes();method = source.getClass().getMethod(name,parameterTypes);Object result = null;if (!method.isAnnotationPresent(MyTransaction.class)){result = method.invoke(source,args);}else {//获取切面类,封装方法//开启事务TransactionStatus transaction = transactionManagement.getTransaction();transaction.start();try {result = method.invoke(source,args);transactionManagement.commit(transaction);}catch (Throwable e){transactionManagement.rollback(transaction);}finally {transactionManagement.close(transaction);}}return result;}});return proxyInstance;}}

相关文章:

手写@EnableTransactionalManagement

定义一个注解&#xff0c;用于标注于方法上&#xff0c;标志着此方法是一个事务方法。 Target({ElementType.METHOD,ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) public interface MyTransaction {}定义一个开启事务功能的注解 Component Import(TransActionBean…...

【Vue】:解决动态更新 <video> 标签 src 属性后视频未刷新的问题

问题描述 在 Vue.js 项目&#xff0c;当尝试动态更新 <video> 标签的 <source> 元素 src 属性来切换视频时&#xff0c;遇到了一个问题&#xff1a;即使 src 属性已更改&#xff0c;浏览器仍显示旧视频。具体表现为用户选择新视频后&#xff0c;视频区域继续显示之…...

网络基础1 http1.0 1.1 http/2的演进史

http1.0 1.1 http/2的演进史&#x1f60e; &#xff08;连接复用 队头阻塞 服务器推送 2进制分帧&#xff09; 概述 我们主要关注的是应用层 传输层 http协议发展历史 http的报文结构&#xff1a;起始行 Header Body http的典型特征 http存在的典型问题 Keep Alive机制 chun…...

Python 通过命令行在 unittest.TestCase 中运行单元测试

文章目录 unittest 模块简介编写单元测试在命令行中运行所有测试在命令行中运行单个测试使用装饰器跳过测试总结常用断言方法 unittest 模块简介 unittest是Python标准库中的一个模块&#xff0c;用于编写和运行单元测试。它提供了一个单元测试框架&#xff0c;使得编写测试用…...

源代码编译安装X11及相关库、vim,配置vim(2)

一、编译安装vim 编译时的cofigure选项如下.只有上一步的X11的包安装全了&#xff08;具体哪些是必须的&#xff0c;哪些是多余的没验证&#xff09;&#xff0c;configure才能认为X的库文件和头文件是可以用的。打开多个编程语言的支持特性。 ./configure --prefixpwd/mybui…...

设计模式 行为型 观察者模式(Observer Pattern)与 常见技术框架应用 解析

观察者模式&#xff08;Observer Pattern&#xff09;是一种行为设计模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时&#xff0c;会通知所有观察者对象&#xff0c;使它们能够自动更新。 一…...

【25考研】川大计算机复试情况,重点是啥?怎么准备?

24年进入复试的同学中&#xff0c;有10位同学的复试成绩为0分。具体是个人原因还是校方原因&#xff0c;还尚不明确。但是C哥提醒&#xff0c;一定要认真复习&#xff01;复试完后不要跟任何人讨论有关复试的题目及细节&#xff01; 一、复试内容 四川大学复试内容较多&#xf…...

C#调用Lua

目录 xLua导入 打包工具导入 单例基类导入与AB包管理器导入 Lua解析器 文件加载与重定向 Lua解析器管理器 全局变量获取 全局函数获取 对于无参数无返回值 对于有参数有返回值 对于多返回值 对于变长参数 完整代码 List与Dictionary映射Table 类映射Table 接口映射…...

LeetCode100之组合总和(39)--Java

1.问题描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复…...

NTN学习笔记之术语和缩写词解析

去发现&#xff0c;去努力&#xff0c;去表达。 参考&#xff1a;3GPP TR 38.811&#xff08;R15&#xff09;&#xff0c;TR 38.821&#xff08;R16&#xff09; 目录 0. NTN典型架构图1. 术语2. 缩写 0. NTN典型架构图 为了方便对术语场景的理解&#xff0c;先放上两张NTN典…...

Yolo11改进:注意力改进|Block改进|ESSAformer,用于高光谱图像超分辨率的高效Transformer|即插即用

摘要 一、论文介绍 高光谱图像超分辨率的重要性:高光谱成像技术通过密集采样光谱特征,为材料区分提供丰富的光谱和空间结构信息,广泛应用于各领域。高光谱图像超分辨率(HSI-SR)旨在从低分辨率HSI生成高分辨率HSI。传统方法的局限性:传统方法依赖手工制作的先验,如低秩近…...

STM32 单片机 练习项目 LED灯闪烁LED流水灯蜂鸣器 未完待续

个人学习笔记 文件路径&#xff1a;程序源码\STM32Project-DAP&DAPmini\1-1 接线图 3-1LED闪烁图片 新建项目 新建项目文件 选择F103C8芯片 关闭弹出窗口 拷贝资料 在项目内新建3个文件夹 Start、Library、User Start文件拷贝 从资料中拷贝文件 文件路径&#xff1a;固…...

使用PyTorch实现基于稀疏编码的生成对抗网络(GAN)在CIFAR-10数据集上的应用

使用PyTorch实现基于稀疏编码的生成对抗网络(GAN)在CIFAR-10数据集上的应用 目录 使用PyTorch实现基于稀疏编码的生成对抗网络(GAN)在CIFAR-10数据集上的应用1. 引言2. 数据集介绍3. 模型网络结构3.1 网络结构3.2 编码器3.3 生成器3.4 判别器4. 模型优化器与损失函数4.1 优…...

用matlab调用realterm一次性发送16进制数

realterm采用PutString接口进行发送&#xff0c;需要注意的是发送的16进制数前面要加入0x标志。只有这样&#xff0c;realterm才能将输入的字符串识别为16进制数的形式。 另外,PutString函数支持两个参数输入&#xff0c;第一个参数为字符串&#xff0c;第二个参数为发送形式&…...

通过可穿戴外骨骼,以更灵活的方式操作你的机器人。

今天&#xff0c;我们将介绍一款专为控制 Mercury X1 和 Mercury B1 机械臂而设计的创新外骨骼。这种外骨骼以人类手臂的结构为蓝本&#xff0c;可实现直观和精确的控制。 开发这种外骨骼的动机源于人们对深度学习和机器学习等领域日益增长的兴趣。这些技术使机器人能够自主学习…...

记录将springboot的jar包和lib分离,使用docker-compose部署

本文讲诉如何把jar里的lib依赖包独立出来&#xff0c;方便更新服务时&#xff0c;缩小jar的体积&#xff0c;下面以若依的system服务为例&#xff0c;配置中的路径请酌情修改&#xff0c;主要提供大致配置逻辑 第一步&#xff1a;修改项目的pom.xml&#xff0c;调整build的配…...

JavaScript 延迟加载的方法

延迟加载&#xff08;Lazy Loading&#xff09;是一种优化网页性能的技术&#xff0c;它允许资源&#xff08;如图片、脚本等&#xff09;在需要时才被加载&#xff0c;而不是在页面初次加载时全部加载。这可以减少初始页面加载时间&#xff0c;提升用户体验&#xff0c;特别是…...

xrdp连接闪退情况之一

错误核查 首先使用命令vim ~/.xsession-errors&#xff0c;当里面的报错信息为WARNING **: Could not make bus activated clients aware of XDG_CURRENT_DESKTOPGNOME environment variable:Failed to execute child process “dbus-launch” (No such file or directory)&am…...

数据分析思维(八):分析方法——RFM分析方法

数据分析并非只是简单的数据分析工具三板斧——Excel、SQL、Python&#xff0c;更重要的是数据分析思维。没有数据分析思维和业务知识&#xff0c;就算拿到一堆数据&#xff0c;也不知道如何下手。 推荐书本《数据分析思维——分析方法和业务知识》&#xff0c;本文内容就是提取…...

WebRTC 在视频联网平台中的应用:开启实时通信新篇章

在当今这个以数字化为显著特征的时代浪潮之下&#xff0c;实时通信已然稳稳扎根于人们生活与工作的方方面面&#xff0c;成为了其中不可或缺的关键一环。回首日常生活&#xff0c;远程办公场景中的视频会议让分散各地的团队成员能够跨越地理距离的鸿沟&#xff0c;齐聚一堂共商…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...

从零开始了解数据采集(二十八)——制造业数字孪生

近年来&#xff0c;我国的工业领域正经历一场前所未有的数字化变革&#xff0c;从“双碳目标”到工业互联网平台的推广&#xff0c;国家政策和市场需求共同推动了制造业的升级。在这场变革中&#xff0c;数字孪生技术成为备受关注的关键工具&#xff0c;它不仅让企业“看见”设…...

Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合

无论是python&#xff0c;或者java 的大型项目中&#xff0c;都会涉及到 自身平台微服务之间的相互调用&#xff0c;以及和第三发平台的 接口对接&#xff0c;那在python 中是怎么实现的呢&#xff1f; 在 Python Web 开发中&#xff0c;FastAPI 和 Django 是两个重要但定位不…...

深度解析云存储:概念、架构与应用实践

在数据爆炸式增长的时代&#xff0c;传统本地存储因容量限制、管理复杂等问题&#xff0c;已难以满足企业和个人的需求。云存储凭借灵活扩展、便捷访问等特性&#xff0c;成为数据存储领域的主流解决方案。从个人照片备份到企业核心数据管理&#xff0c;云存储正重塑数据存储与…...

aurora与pcie的数据高速传输

设备&#xff1a;zynq7100&#xff1b; 开发环境&#xff1a;window&#xff1b; vivado版本&#xff1a;2021.1&#xff1b; 引言 之前在前面两章已经介绍了aurora读写DDR,xdma读写ddr实验。这次我们做一个大工程&#xff0c;pc通过pcie传输给fpga&#xff0c;fpga再通过aur…...