ThreadLocal封装Connection--事务统一管理

Spring代理模式深度解析:从AOP原理到事务模拟实战 代理模式是面向对象编程中一种核心的结构型设计模式,它通过提供一个代理对象来控制对原始对象的访问。其核心原理在于在不修改原始对象代码的前提下,为方法调用添加额外的逻辑,如日志、事务、安全控制等,这体现了面向切面编程(AOP)的思想。这种机制的技术价值在于实现了关注点分离,提升了代码的模块化、可维护性和可扩展性,是构建大型、复杂系统的基石。在Java生态中,Spring框架的AOP功能正是代理模式的典范应用,它广泛应用于声明式事务管理(@Transactional)、缓存(@Cacheable)和日志记录等横切 阅读详情
 

        ThreadLocal:线程本地变量该类提供了线程局部变量。这些变量不同于它们的普通对应物,因为访问一个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的私有静态字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。

        事务是一种机制、是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行。因此事务是一个不可分割的工作逻辑单元。在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的。这特别适用于多用户同时操作的数据通信系统。

       在业务逻辑中我们要统一管理事务,但是在一个事务中会涉及到多个Dao,不同的DAO取得的是不同的Connection对象,这样就不能实现统一管理事务。

       那么怎么才能实现两个或多个DAO用同一个事务来控制,来统一管理事务那?

        首先就要解决一个根本问题,我们在一个事务中,不同的DAO取得的是同一个Connection,这个要怎么实现呢。我们想到了TheadLocal.

        因为当一个业务逻辑要对多个DAO进行处理的时候,此操作属于同一个线程内。所以,我们希望能把此Connection放在线程内,或者和线程有关联。

       在任何一个线程内都可以用ThreadLocal来保存一个变量的copy,这样,如果此对象存在,就可以直接取用。

        如果ThreadLocal中放置connection, 保证事务中的DAO类获取的都是同一个connection,这样才保证事务。所以,在同一个线程内,不同的DAO就可以保证取得到的是同一个Connection

       这样就实现了,事务的统一管理

      ThreadLocal的API如下图:

   下面是ThreadLocal对Connection的封装

 

/*
*采用ThreadLocal封装Connection
*
*/
public Class ConnectionManager {
	
	//创建一个私有静态的并且是与事务相关联的局部线程变量
	private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>;
	
	public static Connection getConnection(){
		//获得线程变量connectionHolder的值conn
		Connection conn = connectionHolder.get();
		if (conn == null){
			  //如果连接为空,则创建连接,另一个工具类,创建连接
				conn = DbUtil.getConnection();
				//将局部变量connectionHolder的值设置为conn
				connectionHolder.set(conn);
		}	
		return conn;
	}

	/**
	 * 关闭连接和从线程变量中删除conn
	 */
	public static void closeConnection(){
		//获得线程变量connectionHolder的值conn
		Connection conn = connectionHolder.get();
		if (conn != null){
			try	{
				//关闭连接
				conn.close();
				//从线程局部变量中移除conn,如果没有移除掉,下次还会用这个已经关闭的连接,就会出错
				connectionHolder.remove();
			}catch(SQLException e){
				e.printStackTrace();
			}
		}
	}
	/**
	 *开启事务,手动开启
	 */
	public static void beginTransaction(Connection conn){
			try {
				//如果连接存在,再设置连接,否则会出错
				if (conn != null){
						//默认conn是自动提交,
						if (conn.getAutoCommit()){
							//关闭自动提交,即是手动开启事务
							conn.setAutoCommit(false);
						}
					}
			}catch(SQLException e){
				e.printStackPrince();
			}
	}
	/**
	 * 提交事务
	 */
	public static void commitTransaction(Connection conn){
		try{
			if (conn != null){
				if (!conn.getAutoCommit()){
					conn.commit();
				}
			}
		}catch(SQLException e){
			e.printStackTrace();
		}
	}
	/**
	 * 回滚事务
	 */
	public static void rollbackTransaction(){
		try {
			if (conn != null){
				if(!conn.getAutoCommit()){
					conn.rollback();
				}
			}	
		}catch(SQLException e){
			e.printStackTrace();
		}	
	}
	
}

以下是业务逻辑事务管理

//调用业务逻辑事务管理
public void addFlowCard(FlowCard flowCard)
		Connection conn = null;
		try {
			//从ThreadLocal中取得Connection
			conn = ConnectionManager.getConnection();
			
				//手动控制事务提交
				ConnectionManager.beginTransaction(conn);
				
			//添加流向单主信息
			flowCardDao.addFlowCardMaster(flowCardVouNo, flowCard);
			
			//添加流向单明细信息
			flowCardDao.addFlowCardDetail(flowCardVouNo, flowCard.getFlowCardDetailList());
			
			if (!conn.getAutoCommit()) {
				//提交事务
				ConnectionManager.commitTransaction(conn);
			}
		}catch(Exception e) {
			e.printStackTrace();
			if (!conn.getAutoCommit()) {
				//回滚事务
				ConnectionManager.rollbackTransaction(conn);
			}
			throw new ApplicationException("操作失败!");
		}finally {
			ConnectionManager.closeConnection();
		}
	}



 

 

【WebLogic】Linux图形化界面安装WebLogic 14.1.2.0 Linux系统图形化界面安装WebLogic 14.1.2.0.0版本 阅读详情

相关推荐

糖尿病预测(深度学习pytorch实现-最新)

本次做的项目是糖尿病的预测,也是来自kaggle上面的一个小项目。根据一个人的怀孕次数、血糖、血压、皮肤厚度、胰岛素指标、身体质量指数、糖尿病谱系指数、年龄等身体参数来预测一个人是否患有糖尿病。

NangoGreen的博客 5358

JAVA学习篇--ThreadLocal,Java中特殊的线程绑定机制

在DRP项目中,我们使用了ThreadLocal来创建Connection连接,避免了一直以参数的形式将Connection向下传递(传递connection的目的是由于jdbc事务要求确保使用同一个connection连接)。那么ThreadLocal是如果做到的呢?它和同步锁的不同在哪里?   是什么:   对于ThreadLocal看英文单词我们很容易理解为一个线程的本地实现,但是它

何静媛 9623

华为IPD实战:从概念到发布的完整流程拆解(附各阶段关键文档模板)

本文深入拆解华为IPD(集成产品开发)从概念到发布的完整实战流程,涵盖概念、计划、开发验证及发布生命周期四大阶段。详细解析了各阶段的核心活动、关键产出与决策评审点,并提供了如《初始业务计划书》等关键文档模板框架,旨在帮助企业将IPD理论转化为可执行的操作指南,提升研发效率与产品成功率。

weixin_29212429的博客 529

ThreadLocal及Connection(jdbc连接池 事务绑定)

1.jdbc连接数据库,就这样子 Class.forName("com.mysql.jdbc.Driver"); java.sql.Connection conn = DriverManager.getConnection(jdbcUrl); 2.通过传入jdbc url用Drivermanager.getConnection(jdbcurl)连接数据库, 注意:一次Drivermanager...

qq_43499096的博客 1600

Ubuntu22.04下ROS2与PX4仿真环境搭建全流程解析

本文详细解析了在Ubuntu22.04系统下搭建ROS2与PX4仿真环境的全流程,包括系统准备、ROS2 Humble安装、PX4飞控环境部署、ROS2与PX4通信桥梁搭建等关键步骤。针对常见问题提供了解决方案,并分享了性能优化和开发调试技巧,帮助开发者快速构建无人机仿真开发环境。

weixin_29248653的博客 607

图数据挖掘 ECC K-core core number truss number clique

K-core:什么叫k-core,给定一个正整数k(k>=0),k-core是一个G的最大子图(也就是说k-core是一个图的限制),将这个子图定义为Hk,对于Hk中的每个顶点v,他的度数都是大于等于k的。 k-core是内嵌的,如下图所示,集合{ABCD}是H3,也就是3-core的子图。而集合{ABCDE}是H2,也就是2-core的子图,集合{ABCDEGF}是H1,也就是1-core的子图,而从集合的角度来讲H3<H2<H1。 core number:什么叫kcor

weixin_45193103的博客 1685

ThreadLocal<Connection>

为什么要学习ThreadLocal? 从上面可以得出:ThreadLocal可以让我们拥有当前线程的变量,那这个作用有什么用呢??? 1.1管理Connection 最典型的是管理数据库的Connection:当时在学JDBC的时候,为了方便操作写了一个简单数据库连接池,需要数据库连接池的理由也很简单,频繁创建和关闭Connection是一件非常耗费资源的操作,因此需要创建数据库连接池~ 那么,数...

weixin_39406672的博客 673

斑马算法优化变分模态分解ZOA-VMD数字信号去噪(优化K值 alpha值)【含Matlab源码 4887期】

斑马算法优化变分模态分解ZOA-VMD数字信号去噪(优化K值 alpha值) 完整的代码,包运行;运行操作视频见优快云资源!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 811

ThreadLocal存储数据库Connection的几种模式

ThreadLocal存储数据库Connection

qq_20671779的博客 789

Windows 下 Claude Code Desktop 安装与使用全记录:从零到一的保姆级图文教程

本文主要介绍了Windows 下 Claude Code 安装全记录:从零到一的保姆级图文教程,希望能对学习使用 Claude Code 的同学们有所帮助。 文章目录 1. 背景 2. 安装Claude Code Desktop 3. 配置第三方API 4. 日常使用

weixin_43178406的博客 8万+

NVIDIA Jetson之远程控制软件NoMachine安装使用

参考:https://www.bilibili.com/video/BV1cg4y1i776?t=12 0 背景

ZONGXP的博客 1万+

ThreadLocal

ThreadLocal 作为 Java 面试的高频题

qq_47125845的博客 497

基于Simulink进行双向DC-DC变换器的仿真建模

特点双向性:可以将能量从一个电压等级转换到另一个,且方向可逆。效率高:通过合理的控制策略减少能量损失。应用广泛:如电池管理系统、混合动力汽车等。挑战拓扑选择:根据应用场景选择合适的电路结构(如buck-boost、full-bridge等)。控制策略:确保高效稳定运行的同时,适应负载变化。热管理:有效散热以保持长期可靠性。首先明确要模拟的任务内容。设计一个能够支持双向能量传输的变换器。根据输入输出电压要求确定合适的变换器拓扑。实现有效的控制策略来维持输出电压稳定。

xiaoheshang_123的博客 367

JDBC工具类(反射版)——新增事务处理

JDBC工具类完善:新增事务处理功能 本讲义在原有JDBC工具类基础上新增了事务处理功能,解决了多SQL操作的原子性问题。核心改进包括: 使用ThreadLocal<Connection>绑定线程连接,确保同一事务使用同一连接 新增事务控制方法:beginTransaction()、commitTransaction()、rollbackTransaction() 优化线程安全和资源管理,避免连接泄露 保留原有通用增删改查功能,完全兼容现有业务代码 关键技术点: 通过setAutoCommit(

专业的计算机毕业设计指南 447

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Spring 声明式事务处理的设计与实现:从 AOP 封装到事务创建、提交与回滚的源码解析

本文基于 doocs/source-code-hunter 仓库中 [Spring事务处理的设计与实现](https://link.gitcode.com/i/b6a1ea498bf4ff03a4282beaabf789d3) 一文,深入剖析 Spring 事务处理模块的源码实现:从编程式事务的基本模型出发,沿着 `TransactionInterceptor` 拦截器 → `Transactio

gitblog_00893的博客 813

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Spring事务管理核心原理与失效场景排查实战

在后台开发中,事务管理是保证数据一致性的基石。Spring 事务本质上建立在数据库连接与 AOP 代理机制之上,通过 TransactionSynchronizationManager 统一管理连接与事务状态。理解传播行为、隔离级别等核心参数,能帮助开发者在不同业务场景下做出正确取舍,例如 REQUIRED 与 REQUIRES_NEW 的差异。然而 @Transactional 并非万能,自调用、异常被吞、多线程切换等都会导致事务失效。掌握失效场景排查方法,能够快速定位线上数据不一致问题。本文从原理到实战

weixin_32518317的博客 93

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Spring与事务处理:声明式事务设计与PlatformTransactionManager源码深度解析

JavaEE 应用中的事务处理是一个重要且涉及范围很广的领域,其实现往往与并发控制、数据一致性等问题深度交织。Spring 作为应用平台,借助 IoC 容器的配置能力与 AOP 的拦截机制,将事务处理的创建、提交、回滚、挂起等通用过程抽象封装,为应用提供了统一、即开即用的声明式事务处理能力。本文以 Spring 事务处理模块的整体设计为骨架,深入 `TransactionProxyFactoryB

gitblog_01182的博客 258

SpringBoot多数据源配置实战:从原理到动态路由落地

在微服务与高并发架构中,一个应用同时访问多个数据库已成为常态。无论是读写分离、独立业务库隔离,还是对接第三方系统,多数据源管理能力都是Java工程师绕不开的核心技能。实现多数据源的关键在于理解Spring抽象路由机制——通过AbstractRoutingDataSource结合ThreadLocal存储线程上下文,再利用AOP切面动态切换数据源标识,从而让一次请求精准路由至目标库。这种设计方案不仅解决了连接池统一管理问题,也为后续扩展动态注册数据源、读写分离负载均衡提供了基础。从企业级管理系统到报表统计平台

weixin_34268310的博客 553

JAVA八股文面试题

在java中供虚拟机理解的代码叫做字节码,即扩展名为.class的文件。java语言通过字节码的方式不仅提高程序的执行效率,而且还保持了解释型语言可移植的特点。作用:a.普通的队列只能作为一个长度有限的缓冲区,如果超出其长度就无法保存该任务,但是阻塞队列可以通过阻塞保留住当前想要继续加入的任务。b.阻塞队列自带注射唤醒功能,可以保证任务队列中没有任务时阻塞获取任务的线程,使得线程进入wait状态,释放cpu资源。原因:在创建新线程的时候,是要获取全局锁的,这个时候其它的就得阻塞,影响了整体效率。

xiao_hu_hu的博客 1080

Feign调用下Seata全局事务XID为空?从原理到排查一次说清

微服务架构中,分布式事务一致性是核心难题。Seata作为主流分布式事务解决方案,通过全局事务XID贯穿调用链路,确保跨服务数据原子性。在Feign远程调用场景下,XID需要借由HTTP Header从调用方传递到被调用方,并绑定线程上下文才能生效。然而,许多团队常遇到“被调用服务Seata事务不开启”或“XID为空”的问题:日志里看不到分支注册,异常时该回滚的未回滚。其根因往往并非Seata依赖缺失,而是Feign拦截器被覆盖、WebMvc配置吞掉请求头、数据源代理失效或版本不一致等隐蔽因素。本文从现象出发

weixin_34059951的博客 214
上一篇: java代理模式--动态代理
下一篇: Java异常机制
Magina-Dota
博客等级 码龄16年 109粉丝 64原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值