达梦数据库的事务管理

达梦数据库的事务管理

在数据库管理系统中,事务是一个重要的概念,它用于保证数据库的一致性和完整性。达梦数据库也提供了事务管理的功能,可以通过事务来实现数据的一致性和完整性。本文将介绍达梦数据库事务的概念、特性、事务隔离级别和事务的应用。

事务的概念

事务是指一组数据库操作,这些操作要么全部执行成功,要么全部失败回滚。事务应该具有以下四个特性,即ACID:

1.原子性(Atomicity):一个事务是一个原子操作,其所有操作要么全部成功,要么全部失败回滚。

2.一致性(Consistency):事务执行前后,数据库的状态应该保持一致,不会因为事务的执行而破坏数据的完整性和一致性。

3.隔离性(Isolation):多个事务并发执行时,每个事务都应该感觉不到其他事务的存在,即每个事务的操作应该是相互独立的。

4.持久性(Durability):事务提交后,对数据库的修改应该是永久性的,即使发生系统故障也不会丢失。

特性

达梦数据库事务具有以下特性:

1.支持隐式提交和显式提交:

1.1用户也可以通过执行COMMIT语句来提交当前的事务:

COMMIT;

1.2DM 数据库在遇到以下 SQL 语句时自动提交前面的事务:

CREATE;
ALTER;
TRUNCATE;
DROP;
GRANT;
REVOKE;
审计设置语句。

2.支持回滚。
除了回滚整个事务之外,DM 数据库的用户还可以部分回滚未提交事务,即从事务的最末端回滚到事务中任意一个被称为保存点的标记处。
将事务回滚到某个保存点的过程如下:
1.只回滚保存点之后的语句;
2.保留该保存点,其后创建的保存点都被清除;
3.释放此保存点之后获得的所有锁,保留该保存点之前的锁。
DM 数据库用户可以使用 SAVEPOINT SAVEPOINT_NAME 命令创建保存点,

SAVEPOINT SAVEPOINT_NAME

使用 ROLLBACK TO SAVEPOINT SAVEPOINT_NAME 命令来回滚到保存点

SAVEPOINT SAVEPOINT_NAME

3.支持并发控制和锁机制。
在高并发的情况下,数据库多个事务同时存取同一数据时,若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。DM采用了多版本并发控制(MVCC) 和封锁机制,防止并发事务修改同一数据,保护数据一致性。

以下以一个简单的例子来验证达梦数据库的多版本并发锁机制:
新建一张TEST表,往里面插入数据::

CREATE TABLE TEST
(ID int,
NAME VARCHAR(30),
AGE int);
insert into TEST 
values(1,'A',10),(2,'B',20),(3,'C',30)
select * from TEST;

假设在一个会话中修改ID为1的数据-- 事务1

UPDATE TEST
SET AGE = 20
WHERE ID = 1; 

在这里插入图片描述

同时在另一个会话中修改ID为1的数据 – 事务2

UPDATE TEST
SET AGE = 30
WHERE ID = 1; 

在这里插入图片描述
此时通过查询V$LOCK视图,查看系统锁的状态,此时可以看到表中被加上了x锁:
在这里插入图片描述

通过查询v$TRXWAIT视图,也可以看到ID为55700的事务被ID为55699的事务阻塞了,
在这里插入图片描述

通过查看v$sessions视图,可以看到被阻塞的语句,事务2与事务1都修改TEST表中的同一行数据时,事务1并未提交事务,认定事务1还没有结束,导致事务2需要等待事务1结束之后才能执行。
在这里插入图片描述

当我们将的事务1提交后,此时事务2也执行成功:
在这里插入图片描述

在这里插入图片描述

DM 数据库支持多用户并发访问、修改数据,有可能出现多个事务同时访问、修改相同数据的情况。这时达梦数据库就会给数据加锁的方法来保证数据一致性和正确性。当事务1在对某个数据库对象进行操作前,需要先对其封锁。封锁后事务2在事务1释放锁之前,不能对此数据库对象进行相应操作。当事务1结束之后,会将对应数据的锁释放,这时事务2才能够对数据库对象进行相应的操作。

事务隔离级别

在SQL-92标准,定义了四种隔离级别:读未提交、读提交、可重复读和串行化,以下列出四种隔离级别下系统允许/禁止哪些类型的读数据现象
在这里插入图片描述
DM数据库支持三种事务隔离级别:读未提交、读已提交和串行化,(另外DM数据库还支持只读事务,只读事务只能访问数据,但不能修改数据)读已提交是DM数据库默认使用的事务隔离级别。
读未提交:
在一个事务中修改了表数据并没有提交 ,但在另一个事务中能读出来你修改表数据了。这就是读未提交。
设置事务的隔离级别为读未提交:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

在窗口一中建表插入数据,
在这里插入图片描述

在窗口一中修改id为1的余额为1500,此时还未提交事务。
在这里插入图片描述

在第二个窗口中打开连接,设置隔离级别为读未提交,查看id为1的balance是1500。此时窗口2读取到窗口1还未提交的事务就是幻读。
在这里插入图片描述

现在假如现在窗口一目前执行的事务不想要了,回滚了,也就是不想修改这一行了,那么窗口二 读取的数据还是修改的这一行,这就是脏读

读已提交:
读已提交,顾名思义,就是可以读取到已经提交事务的内容。

设置事务的隔离级别为读已提交:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

建立一个测试表:

create table account (
id int,
balance int,
name varchar(20)
);
insert into account values(1,1000,'张三'),(2,2000,'李四'),(3,3000,'王五');
commit;
select * from account;

修改id为1的balance值为1500,此时还未提交:
在这里插入图片描述

在窗口2中查看id为1的balance值依旧为1000:在这里插入图片描述
此时在窗口1中将事务提交:
在这里插入图片描述

窗口2中可以看到id为1的值被修改成了1500:在这里插入图片描述
在读已提交的隔离级别中,窗口2在窗口1提交事务前后读取的两次数据的值都不一样,这就是不可重复读;

串行化
是最严格的隔离级别。在Serializable隔离级别下,所有事务按照次序依次执行,各个事务之间完成不可能产生干扰。该级别可以防止脏读、不可重读以及幻读。

设置事务的隔离级别为串行化:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

虽然Serializable隔离级别下的事务具有最高的安全性,但是,由于事务是串行执行,所以效率会大大下降,应用程序的性能会急剧降低。如果没有特别重要的情景,一般都不会使用Serializable隔离级别。
社区地址:https://eco.dameng.com

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值