事务简介:
数据库事务是指作为单个逻辑工作单元的一系列操作的集合。一个典型的事务由应用程序中的一组操作序列组成,对于 DM 数据库来说,第一次执行 SQL 语句时,隐式地启动一个事务,以 COMMIT 或 ROLLBACK 语句/方法显式地结束事务。另外,在执行 DDL 前,DM 数据库会自动把前面的操作进行提交,DDL 前面的操作作为一个完整的事务结束,DDL 语句本身所属事务则根据“DDL_AUTO_COMMIT”配置参数决定是否隐式地提交
COMMIT 操作会将该语句所对应事务对数据库的所有更新持久化(即写入磁盘),数据库此时进入一个新的一致性状态,同时该事务成功地结束。ROLLBACK 操作将该语句所对应事务对数据库的所有更新全部撤销,把数据库恢复到该事务初启动前的一致性状态。
事务的ACID特性:
事务是数据库操作的逻辑工作单元,由一组DML语句(INSERT、UPDATE、DELETE)组成。事务具有四个核心特性:
原子性:事务中的操作要么全部执行成功,要么全部不执行,不存在部分成功。
一致性:事务执行前后数据库从一个一致状态变到另一个一致状态。
隔离性:事务执行不受其他并发事务的干扰。
持久性:事务提交后对数据库的改变是永久的,即使系统故障也不会丢失。
事务提交模式
当事务被提交之后,DM 数据库进行以下操作:
1、将事务所有更改的记录写入日志文件并最终写入到数据文件;
2、释放事务上的所有锁,将事务标记为完成;
3、返回提交成功消息给请求者。
在 DM 数据库中还存在有 3 种事务模式:自动提交模式、手动提交模式和隐式提交模式。
–自动提交模式
所有的 SQL 语句都会在执行结束后提交,或者在执行失败时回滚,此时每个事务都只有一条 SQL 语句。(默认开启)
在 Disql 中,用户也可以通过执行如下语句来设置当前会话为自动提交模式:
SET AUTOCOMMIT ON;
–手动提交模式
此时 Disql 连接到服务器后第一条 SQL 语句或者事务结束后的第一条语句就标记着事务的开始,可以执行 COMMIT 或者 ROLLBACK 来提交或者回滚事务。
–隐式提交模式
在手动提交模式下,当遇到 DDL 语句时,DM 数据库会在执行 DDL 语句之前自动提交前面的事务,然后开始一个新的事务执行 DDL 语句,这种事务提交被称为隐式提交。
DM 数据库在遇到以下 SQL 语句时自动提交前面的事务:
CREATE;
ALTER;
TRUNCATE;
DROP;
GRANT;
REVOKE;
审计设置语句。
事务隔离级别
事务隔离级别定义了事务之间相互隔离的程度,不同级别在数据一致性和并发性能之间做出权衡。
三种并发问题:
脏读:事务B读取到事务A未提交的数据。
不可重复读:同一事务中两次读取同一数据结果不一致。
幻读:事务B读取到事务A新插入的数据。
达梦支持的隔离级别:
READ UNCOMMITTED:可能出现脏读、不可重复读和幻读。最低级别,性能最好,一致性最差。
READ COMMITTED:不可能脏读,可能出现不可重复读和幻读,达梦默认级别,OLTP首选。
SERIALIZABLE:不可能脏读、不可重复读和幻读,是最严格,性能最差,数据最安全的级别。
隔离的实现:
1、采用乐观并发控制(MVCC)与悲观锁相结合的混合策略来高效地解决并发问题。
2、MVCC(多版本并发控制):主要负责解决 "读-写"冲突。它让读操作和写操作互不阻塞,极大地提升了并发性能。
3、锁机制:主要负责解决 "写-写"冲突。当多个事务试图同时修改同一条数据时,通过锁来保证只有一个事务能成功修改,避免数据错乱。
– 查询当前事务隔离级别(会话级)
SELECT * FROM V$TRX;
字段ISOLATION为隔离级别
– 0:读未提交;1:读提交;2:可重复读;3:串行化
– 查询数据库默认隔离级别
SELECT PARA_VALUE FROM V$DM_INI WHERE PARA_NAME = ‘ISOLATION_LEVEL’;
隔离级别选择:
READ COMMITTED:OLTP系统的首选,在读一致性(避免脏读)和并发性能之间取得最佳平衡
SERIALIZABLE:仅在数据一致性要求极高且并发较低的场景使用(如财务报表生成)
READ UNCOMMITTED:一般不推荐,除非对数据准确性要求极低(如统计分析、数据探查)
锁机制与并发控制
达梦数据库通过锁机制实现并发控制,确保数据一致性。
锁模式:
S(共享锁):允许多个事务并发读取,禁止写入 SELECT
X(排他锁):禁止其他事务读写 INSERT、UPDATE、DELETE
IS(意向共享锁):表示低层将加共享锁 表级锁
IX(意向排他锁):表示低层将加排他锁 表级锁
监控锁信息:
– 查看锁信息
SELECT LTYPE, LMODE, BLOCKED, ROW_IDX, TABLE_ID
FROM V$LOCK;
死锁
死锁是指两个或多个事务相互等待对方释放锁,导致所有事务都无法继续执行。
–阻塞事务和被阻塞事务查询
with
lock_wait as(
SELECT l.addr,o.name as 阻塞对象, l.LMODE, l.trx_id, l.tid
FROM vlock l, sysobjects o
WHERE l.table_id = o.id AND blocked = 1),
waiting as (
select a.addr,a.阻塞对象,a.LMODE,b.user_name,b.clnt_host,b.clnt_ip,b.sess_id,'被阻塞的事务: '||b.sql_text,b.trx_id,b.state
from lock_wait a inner join vsessions b on a.trx_id = b.trx_id),
waiting_for as (
select a.addr,a.阻塞对象,a.LMODE,b.user_name,b.clnt_host,b.clnt_ip,b.sess_id,'待提交的事务: '||b.sql_text,b.trx_id,b.state
from lock_wait a inner join v$sessions b on a.tid = b.trx_id)
select * from waiting_for union all
select * from waiting;
文章
阅读量
获赞
