达梦数据库事务机制踩坑:默认不自动提交事务

达梦数据库事务机制踩坑:默认不自动提交事务

在 MySQL、PostgreSQL 等数据库开发中,很多开发者已经习惯了:

text 复制代码
执行SQL
↓
自动提交

但在使用达梦数据库(DM Database)时,经常会遇到这样的问题:

  • SQL执行成功却查不到数据
  • 程序退出后数据丢失
  • Navicat执行Insert没有生效
  • JDBC操作后数据库没有更新

很多时候并不是 SQL 有问题,而是:

text 复制代码
事务没有提交

本文结合实际开发经验,总结达梦数据库事务机制及常见踩坑场景。


目录

  • 达梦数据库简介
  • 什么是事务
  • 自动提交与手动提交
  • 达梦数据库事务特点
  • 常见踩坑场景
  • JDBC中的事务控制
  • Spring事务与达梦数据库
  • 如何查看事务状态
  • 常见问题排查
  • 面试高频问题
  • 总结

一、达梦数据库简介

达梦数据库(DM Database)是国产关系型数据库的重要代表之一。

常见应用领域:

text 复制代码
政府项目

金融系统

国企项目

军工行业

信创项目

官方网站:

text 复制代码
达梦数据库(DM)

目前主流版本:

text 复制代码
DM8

SQL语法与Oracle较为接近。

例如:

sql 复制代码
SELECT *
FROM USER_INFO;

二、什么是事务

事务(Transaction):

一组操作要么全部成功,要么全部失败。

例如:

sql 复制代码
UPDATE ACCOUNT
SET MONEY = MONEY - 100
WHERE ID = 1;

sql 复制代码
UPDATE ACCOUNT
SET MONEY = MONEY + 100
WHERE ID = 2;

如果第一条执行成功:

第二条失败:

text 复制代码
账户金额异常

因此需要事务:

text 复制代码
全部成功

或

全部回滚

三、自动提交与手动提交

数据库事务有两种模式:


自动提交(Auto Commit)

执行:

sql 复制代码
INSERT ...

立即生效:

text 复制代码
自动COMMIT

例如:

text 复制代码
MySQL

默认:

text 复制代码
autocommit = ON

执行:

sql 复制代码
INSERT INTO USER_INFO
VALUES(1,'Tom');

立即写入数据库。


手动提交(Manual Commit)

执行:

sql 复制代码
INSERT ...

不会立刻生效。

需要:

sql 复制代码
COMMIT;

才真正提交。


例如:

sql 复制代码
INSERT INTO USER_INFO
VALUES(1,'Tom');

然后:

sql 复制代码
COMMIT;

数据才持久化。


四、达梦数据库事务特点

很多开发者第一次接触达梦时会踩坑。

因为:

text 复制代码
达梦更强调事务控制

在部分客户端工具和配置环境下:

text 复制代码
不会自动提交事务

例如:

sql 复制代码
INSERT

UPDATE

DELETE

执行后:

text 复制代码
数据可能还在当前事务中

此时:

sql 复制代码
SELECT

当前连接能查到。


但是:

text 复制代码
其他连接查不到

因为:

text 复制代码
事务尚未提交

五、经典踩坑案例

场景一:插入成功却查不到

执行:

sql 复制代码
INSERT INTO USER_INFO
(ID,NAME)
VALUES
(1,'Tom');

返回:

text 复制代码
执行成功

当前连接:

sql 复制代码
SELECT *
FROM USER_INFO;

能看到数据。


重新打开窗口:

sql 复制代码
SELECT *
FROM USER_INFO;

发现:

text 复制代码
查不到

原因:

text 复制代码
未提交事务

解决:

sql 复制代码
COMMIT;

六、场景二:程序退出后数据消失

JDBC代码:

java 复制代码
connection.executeUpdate(sql);

程序结束。


重新查询:

text 复制代码
数据不存在

原因:

java 复制代码
未调用commit()

正确写法:

java 复制代码
connection.commit();

七、场景三:Navicat执行SQL不生效

执行:

sql 复制代码
UPDATE USER_INFO
SET NAME='Jerry'
WHERE ID=1;

提示:

text 复制代码
执行成功

重新查询:

text 复制代码
没有变化

检查:

text 复制代码
自动提交关闭

解决:

sql 复制代码
COMMIT;

或者:

text 复制代码
开启自动提交

八、JDBC事务控制

默认写法:

java 复制代码
Connection conn =
        dataSource.getConnection();

关闭自动提交:

java 复制代码
conn.setAutoCommit(false);

执行SQL:

java 复制代码
statement.executeUpdate(sql);

提交:

java 复制代码
conn.commit();

回滚:

java 复制代码
conn.rollback();

完整示例:

java 复制代码
try {

    conn.setAutoCommit(false);

    statement.executeUpdate(sql1);

    statement.executeUpdate(sql2);

    conn.commit();

} catch (Exception e) {

    conn.rollback();

}

九、Spring事务与达梦数据库

使用Spring后:

java 复制代码
@Transactional

通常不需要手动:

java 复制代码
commit()

Spring会自动处理:

text 复制代码
开启事务

↓

执行SQL

↓

提交事务

例如:

java 复制代码
@Transactional
public void save() {

    mapper.insert(user);

}

执行成功:

text 复制代码
自动提交

发生异常:

text 复制代码
自动回滚

十、如何查看事务状态

查看当前事务:

sql 复制代码
SELECT *
FROM V$TRX;

查看会话:

sql 复制代码
SELECT *
FROM V$SESSIONS;

查看锁:

sql 复制代码
SELECT *
FROM V$LOCK;

常用于排查:

text 复制代码
事务未提交

事务阻塞

死锁问题

十一、事务未提交带来的问题

数据不可见

例如:

text 复制代码
当前连接能查到

其他连接查不到

长事务

事务长期不提交:

text 复制代码
占用资源

导致:

text 复制代码
性能下降

锁无法释放

例如:

sql 复制代码
UPDATE USER_INFO

后不提交。


其他事务:

sql 复制代码
UPDATE USER_INFO

可能被阻塞。


最终:

text 复制代码
系统响应变慢

十二、事务相关SQL

提交事务:

sql 复制代码
COMMIT;

回滚事务:

sql 复制代码
ROLLBACK;

设置自动提交:

sql 复制代码
SET AUTOCOMMIT ON;

关闭自动提交:

sql 复制代码
SET AUTOCOMMIT OFF;

实际使用时应根据客户端工具确认配置。


十三、开发中的最佳实践

1、统一使用Spring事务

推荐:

java 复制代码
@Transactional(
        rollbackFor = Exception.class
)

避免:

java 复制代码
手动commit()

和:

java 复制代码
手动rollback()

大量散落在业务代码中。


2、事务尽量短

不要:

java 复制代码
@Transactional
public void save() {

    Thread.sleep(30000);

}

避免:

text 复制代码
长事务

3、及时提交事务

完成业务后:

sql 复制代码
COMMIT;

避免:

text 复制代码
锁表

阻塞

资源浪费

4、排查工具配置

重点检查:

text 复制代码
Navicat

DBeaver

DataGrip

达梦管理工具

是否开启:

text 复制代码
自动提交

十四、面试高频问题

面试题1

事务是什么?

答案:

text 复制代码
一组操作要么全部成功

要么全部失败

面试题2

COMMIT作用是什么?

答案:

text 复制代码
提交事务

永久保存数据

面试题3

ROLLBACK作用是什么?

答案:

text 复制代码
回滚事务

撤销未提交操作

面试题4

为什么执行成功却查不到数据?

答案:

text 复制代码
事务未提交

面试题5

Spring事务需要手动commit吗?

答案:

text 复制代码
通常不需要

Spring自动管理

面试题6

事务长期不提交会导致什么问题?

答案:

text 复制代码
锁占用

阻塞

性能下降

长事务问题

十五、实际项目经验总结

在达梦项目中最常见的问题:

text 复制代码
SQL执行成功

数据却没有落库

排查步骤:

第一步

确认:

sql 复制代码
COMMIT;

是否执行。


第二步

确认:

java 复制代码
setAutoCommit(false)

是否开启。


第三步

确认:

java 复制代码
@Transactional

是否生效。


第四步

检查:

sql 复制代码
V$TRX

查看事务状态。


总结

达梦数据库开发过程中需要特别关注事务控制。

牢记:

text 复制代码
SQL执行成功

≠

事务提交成功

常见问题本质都是:

text 复制代码
事务没有提交

导致。


核心事务命令:

提交:

sql 复制代码
COMMIT;

回滚:

sql 复制代码
ROLLBACK;

实际项目推荐:

java 复制代码
@Transactional

统一管理事务。

避免手动控制事务导致的问题。


相关推荐
这个DBA有点耶10 分钟前
NULL不是空——数据库里最反直觉的设计,90%新人踩过的坑
数据库·mysql·代码规范
这个DBA有点耶2 小时前
AI写的SQL跑崩了生产库,这锅谁背?
数据库·人工智能·程序员
镜舟科技3 小时前
Databricks 再提 LTAP,AI 时代的数据底座为何重回大一统叙事?
数据库·架构·agent
Databend3 小时前
从湖仓升级为 Agent 时代的数据控制面,Snowflake 和 Databricks 有哪些布局
大数据·数据库·agent
ClouGence7 小时前
SQL Server CDC 能放到 Always On 备库读吗?一文讲透原理与实践
数据库·sql server
先吃饱再说1 天前
存储的进化:从 MySQL 到浏览器缓存,数据到底住在哪?
数据库
Nturmoils1 天前
字段太多看不全,ksql 的展开模式和输出控制怎么用
数据库·后端
Databend1 天前
Agent 轨迹分析与归因的数据工程实践
大数据·数据库·agent
这个DBA有点耶1 天前
SQL改写进阶:标量子查询的“隐形代价”与消除实战
数据库·mysql·架构
smallyoung1 天前
数据库乐观锁深度解析:MySQL、PostgreSQL 实战 + Spring Boot 集成指南
数据库·mysql·postgresql