1.1.原子性 (Atomicity):事务是一个不可分割的工作单元,事务内的所有操作要么全部成功,要么全部失败回滚。
1.2.一致性 (Consistency):事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
1.3.隔离性 (Isolation):多个并发事务之间互不干扰,一个事务的执行不应影响其他事务。
1.4.持久性 (Durability):一旦事务提交,其对数据的修改就是永久性的,即使系统发生故障也不会丢失。
1、事务的开始与结束
1.1开始:
在达梦中,事务通常隐式开始。当执行第一条 SQL 语句(如 INSERT
, UPDATE
, DELETE
, SELECT
)时,一个事务就自动开始了。也可以使用 BEGIN
/ BEGIN TRANSACTION
来显式开始一个事务(但更常见的是设置自动提交模式)。
1.2结束:
事务通过 COMMIT
(提交)或 ROLLBACK
(回滚)来结束。
COMMIT
: 确认所有修改,使其永久化。
ROLLBACK
: 撤销所有未提交的修改。
2、自动提交
2.1 AUTOCOMMIT参数
AUTOCOMMIT
参数,它决定了每条 SQL 语句是否自动作为一个事务提交。
AUTOCOMMIT = ON
(或 1
):默认模式。每条 SQL 语句执行后都会自动提交。你不需要显式地写 COMMIT
。这适用于大多数简单的单条操作。
AUTOCOMMIT = OFF
(或 0
):手动提交模。你需要显式地使用 COMMIT
来提交事务,否则所有的修改都可以被 ROLLBACK
撤销。这对于需要多个操作作为一个原子单元的场景至关重要。
2.2查看和设置自动提交SQL:
查看当前会话的自动提交状态
SELECT DECODE(TRIM(PARA_VALUE), ‘1’, ‘ON’, ‘0’, ‘OFF’, PARA_VALUE) AS “AUTOCOMMIT” FROM V$DM_INI WHERE PARA_NAME = ‘AUTOCOMMIT’;
在当前会话中关闭自动提交
SET AUTOCOMMIT OFF;
在当前会话中开启自动提交
SET AUTOCOMMIT ON;
3、保存点 (SAVEPOINT)
保存点允许你在一个事务内部设置一个标记点。你可以回滚到该标记点,而不需要回滚整个事务。这在复杂的事务中非常有用,允许部分撤销操作。
SAVEPOINT <savepoint_name>
:定义一个保存点。
ROLLBACK TO SAVEPOINT <savepoint_name>
:回滚到指定的保存点。
RELEASE SAVEPOINT <savepoint_name>
:释放一个保存点(在达梦中,通常提交或回滚整个事务后会自动释放所有保存点)。
4、事务隔离级别 (Isolation Level)**
达梦数据库支持 SQL 标准定义的 4 种事务隔离级别,用于控制并发事务之间的可见性。级别从低到高,并发性能从高到低,数据一致性从低到高。
4.1读未提交 (READ UNCOMMITTED):可能读取到其他事务未提交的数据(脏读)。
4.2读已提交 (READ COMMITTED):达梦默认级别。只能读取到其他事务已提交的数据。避免了脏读,但可能出现不可重复读和幻读。
4.3可重复读 (REPEATABLE READ):保证在同一个事务中,多次读取同一数据的结果是一致的。避免了脏读和不可重复读,但可能出现幻读。
4.4序列化 (SERIALIZABLE):最高隔离级别,完全串行化执行,避免所有并发问题(脏读、不可重复读、幻读),但性能开销最大。
4.5设置隔离级别SQL
设置当前会话的事务隔离级别为 READ COMMITTED
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
设置当前会话的事务隔离级别为 SERIALIZABLE
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
(注意:设置通常在事务开始前进行)
创建一个测试表
create table “account”
(
“ID” INT not null ,
“name” VARCHAR2(50),
“balance” NUMBER(10, 4),
primary key(“ID”)
)
insert into “account”(“ID”, “name”, “balance”) VALUES(1, ‘张三’, 10000);
insert into “account”(“ID”, “name”, “balance”) VALUES(2, ‘李四’, 10000);
现在模拟张三向李四转账 1000 元,这是一个经典的事务场景,必须保证两个 UPDATE 操作原子性。
COMMIT;
开始转账业务
UPDATE account SET balance = balance - 1000 WHERE name = ‘张三’;
UPDATE account SET balance = balance + 1000 WHERE name = ‘李四’;
如果业务逻辑检查无误,提交事务
COMMIT;
SELECT * FROM account;
文章
阅读量
获赞