Oracle-Java JDBC 连接超时之后的认知纠正
背景
偶然读到熊老师的文章《老熊的三分地-JDBC中语句超时与事务》了解到:JAVA代码的最后正常断开数据库连接,在默认情况下,正常断开的数据库连接会自动提交没有提交的事务。
通过文章的测试JAVA程序,可以表明,JDBC中的语句超时,只会使当前的SQL中止运行,但如果是在一个事务中,之前运行的DML语句并没有提交。这造成的后果有两种:
- 如果是连接池,那么超时之前更新的数据可能会被其他请求重用时得以提交,或者是在连接释放时得以提交,这造成数据的不一致,因为不是一个逻辑上有效的事务。
- 由于数据被更新而没有及时回滚,可能会导致应用重新发起相同的事务时被锁住。如果被锁住的会话仍然有超时中止的机制,那么这种情况就会越来越严重。
- 为了避免以上的两种问题,在超时后,应该主动发起一次ROLLBACK操作。
今天正好有国产数据库工程师师给我们培训的时候也提到了这一点,表示:“JDBC连接ORACLE,在断开连接时会把未提交的事务进行提交,在Oracle 23ai版本进行了修复,其它数据库都是回滚事务。”
这着(zhuo)实有点刷新我对Oracle的基础认知。这是一篇对自己认知纠正的测试文章。复现一下熊老师的测试,实践出真知。
环境准备
- Oracle 版本
SQL*Plus: Release 11.2.0.3.0 Production on Tue Nov 19 21:32:31 2024
- 安装JAVA
[root@db ~]$ mkdir /usr/local/java
[root@db ~]$ cd /usr/local/java
[root@db java]$ mv /root/jdk-11.0.21_linux-x64_bin.tar.gz ./
[root@db java]$ tar -zxvf jdk-11.0.21_linux-x64_bin.tar.gz
[root@db java]$ cd jdk-11.0.21
[root@db jdk-11.0.21]# pwd
/usr/local/java/jdk-11.0.21
[root@db jdk-11.0.21]# vi /etc/profile
...
export JAVA_HOME=/usr/local/java/jdk-11.0.21
export CLASSPATH=$JAVA_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin
...
[root@db ~]# source /etc/profile
[root@db ~]# java -version
java version "11.0.21" 2023-10-17 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.21+9-LTS-193)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.21+9-LTS-193, mixed mode)
- Oracle 用户环境变量
[oracle@db ~]$ cat .bash_profile
......
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
export JAVA_HOME=/usr/local/java/jdk-11.0.21
export CLASSPATH=$JAVA_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin
......
[oracle@db ~]$ source .bash_profile
[oracle@db ~]$ java -version
java version "11.0.21" 2023-10-17 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.21+9-LTS-193)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.21+9-LTS-193, mixed mode)
- JAVA代码:
[oracle@db java_oracle]$ cat TestTimeout.java import java.sql.*;public class TestTimeout {public static Connection getConnection() throws Exception {String driver = "oracle.jdbc.driver.OracleDriver";String url = "jdbc:oracle:thin:@10.10.5.64:1521/phytest1";Class.forName(driver);return DriverManager.getConnection(url, "two", "two");}public static void main(String args[]) {test1();}public static void test1() {Connection conn = null;Statement pstmt = null;try {conn = getConnection();conn.setAutoCommit(false);pstmt = conn.createStatement();pstmt.setQueryTimeout(60);System.out.println("连接成功!");ResultSet rs = pstmt.executeQuery("select userenv('sid') sid from dual");while (rs.next()) {System.out.println("SID:" + rs.getString("sid"));}rs.close();pstmt.execute("insert into t1 values (1,userenv('sid'),'xx')");System.out.println("Insert t1 succeed!");pstmt.execute("update t2 set name='x' where id=1");System.out.println("Update t2 succeed!");conn.commit();} catch (Exception e) {e.printStackTrace();try {System.out.println("等待......");Thread.sleep(300000);} catch (Exception f) {}} finally {try {System.out.println("关闭连接!");pstmt.close();conn.close();} catch (SQLException e) {e.printStackTrace();}}} }
- 将ojdbc8_jar.zip放在项目目录,下载:ojdbc8_jar.zip
[oracle@db java_oracle]$ ls ojdbc8.jar TestTimeout.java
- 通过javac 编译代码生成:TestTimeout.class
[oracle@db java_oracle]$ javac TestTimeout.java
[oracle@db java_oracle]$ ls
ojdbc8.jar TestTimeout.class TestTimeout.java
- 测试执行java
[oracle@db java_oracle]$ java -cp .:ojdbc8.jar TestTimeout
连接成功!
SID:387
Insert t1 succeed!
Update t2 succeed!
关闭连接!
- 查看数据
TWO@phytest1:1489> select * from t1;ID SID NAME
---------- -------------------- ----------------1 387 xx
- 配置sqlplus 显示: 用户名@实例名:SID
[oracle@db ~]$ cat /u01/oracle/11.2.0.3/product/sqlplus/admin/glogin.sql
SET TERMOUT OFF
DEFINE sqlprompt=none
COLUMN sqlprompt NEW_VALUE sqlprompt
SELECT USER ||'@'|| NVL('&_CONNECT_IDENTIFIER', global_name )||':'|| userenv('sid') sqlprompt FROM global_name;
SET SQLPROMPT '&sqlprompt> '
UNDEFINE sqlprompt
SET TERMOUT ON
col NAME format a50
col VALUE format a50
set lin 250
set pagesize 500
[oracle@db ~]$ sqlplus / as sysdba
SYS@phytest1:387>
复现:熊老师文章的操作流程
- SID:1489 表准备:T1、T2:
TWO@phytest1:1489> create table t1 ( id number primary key,sid varchar2(20),name varchar2(20));
Table created.
TWO@phytest1:1489> create table t2 ( id number primary key,sid varchar2(20),name varchar2(20));
Table created.
TWO@phytest1:1489> insert into t2 values (1,userenv('sid'),'a');
1 row created.
TWO@phytest1:1489> commit;
Commit complete.
TWO@phytest1:1489> select * from t2;ID SID NAME
---------- -------------------- --------------1 1489 a
- SID:1489 将T2表中ID=1的记录进行UPDATE操作,但是不提交。
TWO@phytest1:1489> update t2 set name='y' where id=1;
1 row updated.
TWO@phytest1:1489>
- 执行java 程序
[oracle@db java_oracle]$ java -cp .:ojdbc8.jar TestTimeout
连接成功!
SID:659
Insert t1 succeed!
- sid:74 执行update表T2时会被锁住
SYS@phytest1:74> set line 800
SYS@phytest1:74> col EVENT for a50
SYS@phytest1:74> select sid,event,sql_id from v$session where sid=659;SID EVENT SQL_ID
---------- ------------------------------------- ----------659 enq: TX - row lock contention 3b3b7s22dv13t
- 查看锁信息
col blocker for a10
SELECT (SELECT usernameFROM v$sessionWHERE SID = a.SID) blocker, a.SID, 'is blocking',(SELECT usernameFROM v$sessionWHERE SID = b.SID) blockee, b.SIDFROM v$lock a, v$lock bWHERE a.BLOCK = 1 AND b.request > 0 AND a.id1 = b.id1 AND a.id2 = b.id2;BLOCKER SID 'ISBLOCKING BLOCKEE SID
---------- ---------- ----------- ------------------------------ ----------
TWO 659 is blocking TWO 277
- 操作截图
- 查看事务的状态
select start_time,xidusn,xidslot,xidsqn,status from v$transaction where ses_addr=(select saddr from v$session where sid=387);select * from v$lock where sid=387;
-- 取TM锁对象id(v$lock.ID1)
select owner,object_name,object_type from dba_objects where object_id in (256012);
-
操作截图
-
如熊老师文章所示,超时关闭连接后insert 插入成功
验证下Oracle与Mysql 退出
Oracle 退出小测试,结果已提交
Mysql 退出小测试,结果已回滚
总结
- 1、通过复现熊老师的测试,确认JDBC在会话超时后会把未提交的数据进行提交处理;
- 2、通过验证Oracle与Mysql 的退出,Oracle 确实在关闭自动提交后,退出仍然会提交;
- 3、程序在做异常处理时一定要加rollback;
- 4、重要的事情说三遍:细节、细节、细节,不能忽略,不能有惯性思维;
- 5、Python-JDBC-Oracle 测试脚本下载
欢迎赞赏支持或留言指正
相关文章:

Oracle-Java JDBC 连接超时之后的认知纠正
背景 偶然读到熊老师的文章《老熊的三分地-JDBC中语句超时与事务》了解到:JAVA代码的最后正常断开数据库连接,在默认情况下,正常断开的数据库连接会自动提交没有提交的事务。 通过文章的测试JAVA程序,可以表明,JDB…...
自定义数据集使用框架的线性回归方法对其进行拟合
代码 import torch import numpy as np import torch.nn as nncriterion nn.MSELoss()data np.array([[-0.5, 7.7],[1.8, 98.5],[0.9, 57.8],[0.4, 39.2],[-1.4, -15.7],[-1.4, -37.3],[-1.8, -49.1],[1.5, 75.6],[0.4, 34.0],[0.8, 62.3]])x_data data[:, 0] y_data data…...

15天基础内容-5
day13 【String类、StringBuilder类】 主要内容 String类常用方法【重点】 String类案例【重点】 StringBuilder类【重点】 StringBuilder类常用方法【重点: append】 StringBuilder类案例【理解】 第一章String类 1.1 String类的判断方法 String类实现判断功能…...

82,【6】BUUCTF WEB .[CISCN2019 华东南赛区]Double Secret
进入靶场 提到了secret,那就访问 既然这样,那就传参看能不能报错 这个页面证明是有用的 传参长一点就会报错,传什么内容无所谓 所以网站是flask框架写的 有一个颜色深一点,点开看看 rc4加密url编码 import base64 from urllib…...

Android WebView 中网页被劫持的原因及解决方案
文章目录 一、原因分析二、解决方案一览三、解决方案代码案例3.1 使用 HTTPS3.2 验证 URL3.3 禁用 JavaScript3.4 使用安全的 WebView 设置3.5 监控网络请求3.6 使用安全的 DNS 四、案例深入分析4.1 问题4.2 分析 五、结论 在 Android 应用开发中,WebView 是一个常用…...
特朗普政府将开展新网络攻击
近日,特朗普政府已表态:减少物理战争,网络战将代替,以实现美国的全球优势。 特朗普也指示美国网络司令部可以在没有总统批准的情况下开展更广泛行动,尤其是应对一些突发事件,这其实成为了后续美国通过网络…...

快递代取项目Uniapp+若依后端管理
快递接单代取得uniappspringboot项目 实际效果图...

arcgis短整型变为长整型的处理方式
1.用QGIS的重构字段工具进行修改,亲测比arcgis的更改字段工具有用 2.更换低版本的arcgis10.2.2,亲测10.5和10.6都有这个毛病,虽然官方文档里面说的是10.6.1及以上 Arcgis10.2.2百度链接:https://pan.baidu.com/s/1HYTwgnBJsBug…...

06、Redis相关概念:缓存击穿、雪崩、穿透、预热、降级、一致性等
Redis相关概念:缓存击穿、雪崩、穿透、预热、降级、一致性等 Redis缓存雪崩、缓存击穿、缓存预热热点key、缓存降级、短链接、分布式锁秒杀、预减库存、 堆外缓存Redis架构设计、Redis动态刷新、Redis和DB双写一致性、过期删除策略、集群数据倾斜等一、缓存雪崩 缓…...
嵌入式基础 -- PCIe 控制器中断管理之MSI与MSI-X简介
PCIe 控制器中断管理技术文档 1. 背景 在现代计算机系统中,中断是设备与 CPU 通信的重要机制,PCIe 控制器提供了从传统线中断到基于消息的中断(MSI/MSI-X)的演进,以提升中断处理效率和可扩展性。x86 和 ARM 架构虽然…...

websocket实现
由于安卓资源管理器展示的路径不尽相同,各种软件保存文件的位置也不一定一样.对于普通用户上传文件时,查找文件可能是一个麻烦的事情.后来想到了一个办法,使用pc端进行辅助上传. 文章目录 实现思路1.0 实现定义web与客户端通信数据类型和数据格式web端websocket实现web端对客户…...

unity学习20:time相关基础 Time.time 和 Time.deltaTime
目录 1 unity里的几种基本时间 1.1 time 相关测试脚本 1.2 游戏开始到现在所用的时间 Time.time 1.3 时间缩放值 Time.timeScale 1.4 固定时间间隔 Time.fixedDeltaTime 1.5 两次响应时间之间的间隔:Time.deltaTime 1.6 对应测试代码 1.7 需要关注的2个基本…...

【C++】特殊类设计、单例模式与类型转换
目录 一、设计一个类不能被拷贝 (一)C98 (二)C11 二、设计一个类只能在堆上创建对象 (一)将构造函数私有化,对外提供接口 (二)将析构函数私有化 三、设计一个类只…...

scratch七彩六边形 2024年12月scratch三级真题 中国电子学会 图形化编程 scratch三级真题和答案解析
目录 scratch七彩六边形 一、题目要求 1、准备工作 2、功能实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、…...

代码随想录刷题day16|(哈希表篇)349.两个数组的交集
目录 一、哈希表理论基础 二、集合set在哈希法中的应用 三、相关算法题目 四、相关知识点 1.set集合特点和常用方法 1.1 set集合概述 1.2 set集合特点 1.3 常用方法 2.set集合转换成数组 法1:另新建一个数组 法2:将结果集合转为数组 ▲ 3.数组…...

Synology 群辉NAS安装(6)安装mssql
Synology 群辉NAS安装(6)安装mssql 写在前面mssql 2019:成功安装说明,这个最终成功了 mssql 2022没有成功1. pull image2.启动mssql docker container 远程连接 写在前面 mssq是一个重要节点。 这是因为我对mysql没有一丝好感。虽然接触了许…...

2025年美赛B题-结合Logistic阻滞增长模型和SIR传染病模型研究旅游可持续性-成品论文
模型设计思路与创新点: 建模的时候应该先确定我们需要建立什么类的模型?优化类还是统计类?这个题需要大量的数据分析,因此我们可以建立一个统计学模型。 统计学建模思路:观察规律,建立模型,参…...

Hook 函数
什么是hook函数? 在计算机编程中,hook函数是指在特定的事件发生时被调用的函数,用于在事件发生前或后进行一些特定的操作。通常,hook函数作为回调函数被注册到事件处理器中,当事件发生时,事件处理器会自动…...

蓝桥杯模拟算法:蛇形方阵
P5731 【深基5.习6】蛇形方阵 - 洛谷 | 计算机科学教育新生态 我们只要定义两个方向向量数组,这种问题就可以迎刃而解了 比如我们是4的话,我们从左向右开始存,1,2,3,4 到5的时候y就大于4了就是越界了&…...

DeepSeek-R1解读:纯强化学习,模型推理能力提升的新范式?
DeepSeek-R1解读:纯强化学习,模型推理能力提升的新范式? 1. Impressive Points2. 纯强化学习,LLM推理能力提升新范式?2.1 DeepSeek-R1-Zero2.2 DeepSeek-R1 3. 端侧模型能力提升:蒸馏>强化学习 1. Impre…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...

DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...

【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...