JDBCToolsV2:利用ThreadLocal保证当前线程操作同一个数据库连接对象。
JDBCToolsV2: 利用ThreadLocal保证当前线程操作同一个数据库连接对象。
package com.dgd.test; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties; public class JDBCToolsV2 { private static DataSource ds;
private static ThreadLocal<Connection> th;
//静态代码块,创建数据库连接池
static {
try {
Properties p=new Properties();
p.load(JDBCToolsV1.class.getClassLoader().getResourceAsStream("druid.properties"));
ds= DruidDataSourceFactory.createDataSource(p);
th=new ThreadLocal<>();
} catch (Exception e) {
e.printStackTrace();
}
} public static Connection getConnection(){
//方式1: DriverManger.getConnection();
//方式2: 数据库连接池, ds.getConnection();
try {
Connection conn=th.get(); //获取当前线程的共享连接对象
if(conn==null) //当前线程没有拿过连接,第一个获取连接
{
conn=ds.getConnection();//从线程池中哪一个新的
th.set(conn); //放到当前线程共享变量中
}
return conn;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
//关闭连接方法
public static void free( Connection conn){
try {
Connection conn=th.get(); //获取当前线程的共享连接对象
if(conn!=null) //当前线程获取连接
{
conn.close(); //关闭当前数据库连接
}
th.set(null); //将ThreadLocal设置为空,防止上次关闭,下次获取一个关闭的数据库连接
} catch (SQLException e) {
e.printStackTrace();
}
} public static int update3( String sql, Object... args) throws SQLException {
Connection conn=getConnection();
PreparedStatement ps=conn.prepareStatement(sql);
if(args!=null && args.length>0)
{
for (int i = 0; i <args.length ; i++) {
ps.setObject(i+1,args[i]);
}
}
int len=ps.executeUpdate();
ps.close();
return len;
}
}
Test:
package com.dgd.test; import org.junit.Test; import java.sql.Connection;
import java.sql.SQLException; public class TestJDBCToolV1 { @Test
public void test2() throws SQLException {
String sql1="INSERT INTO COURSE VALUES(NULL,?)";
String sql2="INSERT INTO COURSE VALUES(NULL,?)";
Connection conn= JDBCToolsV2.getConnection(); conn.setAutoCommit(false);
try {
int len1=JDBCToolsV2.update3(sql1,"美术");
int len2=JDBCToolsV2.update3(sql2,"体育");
if(len1>0 && len2>0)
{
conn.commit();
}
else
{
conn.rollback();
}
} catch (SQLException e) {
conn.rollback();
}
conn.setAutoCommit(true);
JDBCToolsV2.free(conn); }
}
JDBCToolsV2:利用ThreadLocal保证当前线程操作同一个数据库连接对象。的更多相关文章
- Java多线程理解:线程安全的集合对象
1.概念介绍 线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用.不会出现数据不一致或者数据污染. 线程不安全就 ...
- 多个线程怎样操作同一个epoll fd
自己曾经做一个接口server时候,这样的场景下我的设计是多个线程操作同一个epoll fd.彼时,我的理由是epoll的系列函数是线程安全的. 当然有人不理解为什么会有多个线程操作同一个epoll ...
- 线程系列5--java中的ThreadLocal类实现线程范围内的数据共享(二)
ThreadLocal类可以理解成一个类似与map集合使用,以当前线程当做key 来使用,将线程氛围内需要共享的数据当做value,形成键值对的形式使用.ThreadLocal和线程同步机制都是为了解 ...
- 8.12 day31 进程间通信 Queue队列使用 生产者消费者模型 线程理论 创建及对象属性方法 线程互斥锁 守护线程
进程补充 进程通信 要想实现进程间通信,可以用管道或者队列 队列比管道更好用(队列自带管道和锁) 管道和队列的共同特点:数据只有一份,取完就没了 无法重复获取用一份数据 队列特点:先进先出 堆栈特点: ...
- python并发编程-进程间通信-Queue队列使用-生产者消费者模型-线程理论-创建及对象属性方法-线程互斥锁-守护线程-02
目录 进程补充 进程通信前言 Queue队列的基本使用 通过Queue队列实现进程间通信(IPC机制) 生产者消费者模型 以做包子买包子为例实现当包子卖完了停止消费行为 线程 什么是线程 为什么要有线 ...
- java 多线程 线程安全及非线程安全的集合对象
一.概念: 线程安全:就是当多线程访问时,采用了加锁的机制:即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读取完之后,其他线程才可以使用.防止出现数据不一致或 ...
- Java多线程操作同一个对象,线程不安全
Java多线程操作同一个对象 发现问题:多个线程操作同一资源的情况下,线程不安全,数据紊乱 代码: package multithreading; // Java多线程操作同一个对象 // 买火车票的 ...
- 用ThreadLocal类实现线程安全的正确姿势
大家通常知道,ThreadLocal类可以帮助我们实现线程的安全性,这个类能使线程中的某个值与保存值的对象关联起来.ThreadLocal提供了get与set等访问接口或方法,这些方法为每个使用该变量 ...
- VC中利用多线程技术实现线程之间的通信
当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...
随机推荐
- XCTF练习题---MISC---can_has_stdio?
XCTF练习题---MISC---can_has_stdio? flag:flag{esolangs_for_fun_and_profit} 解题步骤: 1.观察题目,下载附件 2.打开发现是由tra ...
- python3 常见错误(一)
以下全部是在python3中适用. 错误一: 函数默认参数 Python允许为函数的参数提供默认的可选值.但是它可能会导致一些易变默认值的混乱.例子: 我们希望每次调用myFun函数,list1都为默 ...
- SpringBoot从0到0.7——第三天
SpringBoot从0到0.7--第三天 今天学习整合JDBC,连接数据库的增删改查,写出来容易,理解原理读懂代码才是主要的. 首先创建项目,勾选上一下模块 在application.yml添加 s ...
- 蓝桥杯Web练习题:多个斜线开始的路径重定向问题
多个斜线开始的路径重定向问题 需求说明 在 vue-router v3.5.2 版本代码中存在一个 Bug,一个以多个斜线(///)开始的路径实际上可能会重定向到另一个域.这是因为 cleanPath ...
- Java课程课堂作业代码
前言 本文章只是单纯记录课堂老师布置的课堂作业代码,题目都比较简单,所以没有写解题思路,相信大家都能理解,当然其中有的解法和代码不是最优的,当时只是为了完成题目,后来也懒得改了,如果有不恰当或者不正确 ...
- hooks 与 animejs
hooks 与 animejs 本文写于 2020 年 1 月 13 日 animejs 是现如今非常不错的一个 js 动画库.我们将其与 React Hooks 融合,使它更方便的在 React 中 ...
- if判断+while循环
1.常量 纯大写字母命名常量名,如:AGE_OF_OLDBOY=18 常量的值是可以改变的,如:AGE_OF_OLDBOY=19 2.基本运算符 (1).算术运算 +.-.*./ ...
- vs.net调试ArcGIS Engine代码查看变量时,提示“要检查本机对象,请启用本机代码调试。” 的解决方法
用vs2017 调试 查看ArcGIS Engine 的变量时 会提示如下图所示的错误: 解决方法: 工具->选项->调试->常规->使用托管的兼容模式 如下图所示: 2.设置 ...
- df-查看磁盘目录空间大小
查看磁盘分区挂载情况. 语法 df [option] 选项 -T 显示文件系统类型. -h 带单位显示. 示例 [root@localhost ~]# df -Th Filesystem Type S ...
- yolov5训练自定义数据集
yolov5训练自定义数据 step1:参考文献及代码 博客 https://blog.csdn.net/weixin_41868104/article/details/107339535 githu ...