达梦事务管理

事务

1.事务简介

数据库事务是指作为单个逻辑工作单元的一系列操作的集合。一个典型的事务由应用程

序中的一组操作序列组成。

1.1事务特性

1.1.1原子性

这一组操作要么一起生效,要么都不生效,事务执行过程中如遇错误,已经执行的操作要全部撤回,这就是事务的原子性。

1.1.2 一致性

数据一致性是指表示客观世界同一事务状态的数据,不管出现在何时何处都是一致的、

正确的、完整的。换句话说,数据一致性是任何点上保证数据以及内部数据结构的完整性,

比如账户之间无论怎么转账,总额不会变等现实约束;年龄不能为负值。

1.1.3隔离性

事务是隔离的,意味着每个事务的执行效果与系统中只有该事务的执行效果一样,也就

是说,某个并发事务所做的修改必须与任何其他的并发事务所做的修改相互隔离。

数据库为了提高资源利用率和事务执行效率、降低响应时间,允许事务并发执行。但是多个事务同时操作同一对象,必然存在冲突,事务的中间状态可能暴露给其它事务,导致一些事务依据其它事务中间状态,把错误的值写到数据库里。需要提供一种机制,保证事务执行不受并发事务的影响,让用户感觉,当前仿佛只有自己发起的事务在执行,这就是隔离性。

1.1.4 持久性

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其

他操作和数据库故障不应该对其有任何影响。

数据只要存储非易失存储介质,宕机就不会导致数据丢失。因此数据库可以采用以下方法来保证持久性:

  1. 事务完成前,所有的更改都保证存储到磁盘上了。

(2)提交完成前,事务的更改信息,以日志的形式存储在磁盘,重启过程根据日志恢复出数据库系统的内存状态。

1.2事务开始

对于 DM 数据库来说,第一次执行 SQL 语句时,隐式地启动一个事务。

1.3事务结束

1.3.1显示事务结束

COMMIT 或 ROLLBACK 语句/方法显式地结束事务。

1.3.2隐示事务结束

1)当连接的属性设置为自动提交时,每执行一条语句都会提交事务。

2)在执行 DDL 前,DM 数据库会自动把前面的操作进行提交,DDL 前面的操作作为一个完整的事务结束。DDL 语句本身所属事务则根据“DDL_AUTO_COMMIT”配置参数决定是否隐式地提交(注意,无论DDL_AUTO_COMMIT 参数如何设置,ALTER TABLESPACE 和 ALTER USER 操作总是自动提交的)。

3)事务所在的程序正常结束和用户退出;

4)系统非正常终止时。

1.4保存点

为了提高事务管理的灵活性,数据库还提供了设置保存点(SAVEPOINT)和回滚到保存点的功能。保存点提供了一种灵活的回滚,事务在执行中可以回滚到某个保存点,在该

保 存 点 以 前 的 操 作 有 效 , 而 以 后 的 操 作 被 回 滚 掉 。 可 以 使 用 SAVEPOINT SAVEPOINT_NAME 命令创建保存点,使用 ROLLBACK TO SAVEPOINT SAVEPOINT_NAME。

create table t3(c1 int,c2 int);

insert into t3 values(1,1);

--创建保存点a

savepoint a;

insert into t3 values(2,2);

select * from t3;

 

--回滚到保存点a,再次查看t3,可以看到t3之前插入的数据没有回滚

rollback to savepoint a;

select * from t3;

 

2.事务隔离级别

2.1三种读数据类型

2.1.1脏读

如果一个事务在提交操作结果之前,另一个事务可以看到该结果,就会发生脏读。

脏读只有在读未提交的隔离级别下才会发生。读未提交隔离级别是最不严格的隔离级别。

会话1

会话2

create table t3(c1 int,c2 int);

insert into t3 values(1,1);

commit;

select * from t3;

 

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

insert into t3 values(2,2);--不提交

select * from t3;

 

从上面可以看到,在设置读未提交的隔离级别下,会话1可以读到会话2未提交的事务。

2.1.2不可重复读

一个事务先后读取同一条记录,但两次 读取的数据不同,称之为不可重复读。

这个很好理解,比如A用户在查询某张表的某条记录时,B用户修改了这了一条数据,那么A用户再次查询的时候与上次查询的结果不一致。即原始读取不可重复

会话1

会话2

select * from t3 where c2=1;

 

update t3 set c1=2 where c2=1;

commit;

select * from t3;

 

可以看到会话1两次查询的同一条记录不一致。要避免此问题可以加行锁

会话1

会话2

select * from t3 where c2=1 for update;

update t3 set c1=1 where c2=1;

 

写被读阻塞。另外还可以将事务隔离级别设置为可重复读,但是达梦不支持此隔离级别。可以设置为串行化来避免这种情况。

2.1.3幻读

一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为幻像读。

幻觉读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么后面就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样,称之为幻读。

会话1

会话2

select * from t3;

 

update t3 set c2=3;

commit;

insert into t3 values(4,4);

commit;

select * from t3;

 

会话1没有查询到自己预期的结果,感觉像发生了幻觉一样。要想避免幻读,只能将事务隔离级别设置为串行化。

会话1

会话2

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

select * from t3;

 

insert into t3 values(3,3);

insert into t3 values(4,4);

commit;

select * from t3;

 

select * from t3;

 

update t3 set c2=4;

commit;

 

select * from t3;

 

可以看到会话2中的操作,并不会影响会话1中的查询。

2.1.4 不可重复读与脏读区别

不可重复读侧重某一行数据发生了变化。

幻读侧重行数量发生了变化;

同一个事务中,某一行之前没有,后来读到了,那我认为读到幻影行了(比如其他事务插入了新行)不可重复读。

广义上讲,第一次读和第二次读数据不一样了,这包含两种情况:

  1. 同一行数据发生了变化;
  2. 行数量发生了变化;

为了区分来这两种情况,就把后者单独叫“幻读”,而不可重复读通常指的就是第一种情况。

所以“不可重复读”和“幻读”都是读的过程中数据前后不一致,只是前者侧重于修改,后者侧重于增删。个人认为,严格来讲“幻读”可以被称为“不可重复读”的一种特殊情况。但是从数据库管理的角度来看二者是有区别的。解决“不可重复读”只要加行级锁就可以了。而解决“幻读”则需要加表级锁。

2.2三种事务隔离级别

2.2.1读提交

读提交隔离可以确保只访问到已提交事务修改的数据,保证数据处于一致性状态,能够满足大多数应用的要求,并最大限度的保证系统并发性能,但可能会出现不可重复读取和幻像读。读提交是DM数据库默认使用的事务隔离级别,可重复读升级为更严格的串行化隔离级。

用户可以在事务开始时使用以下语句设定事务为读提交隔离级:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

2.2.2读未提交

读未提交隔离级别是最不严格的隔离级别。实际上,在使用这个隔离级别时,有可能发

生脏读、不可重复读和幻像。一般来说,读未提交隔离级别通常只用于访问只读表和只读视图,以消除可见性判断带来的系统开销,提升查询性能。

用户可以在事务开始时使用以下语句,设定事务为读未提交隔离级:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

2.3.3串行化

在要求消除不可重复读取或幻像读的情况下,我们可以设置事务隔离级为串行化。跟读

提交隔离级相比,串行化事务的查询本身不会增加任何代价,但修改数据可能引发“串行化

事务被打断”错误。

用户可以在事务开始时使用以下语句设定事务为串行化隔离级:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

2.3.4只读事务

除了前面所述的各种标准特性外,DM 数据库还支持只读事务,只读事务只能访问数据,

但不能修改数据。并且只读事务不会改变事务原有的隔离级。

用户可以在事务开始时使用以下语句,设定事务为只读事务:

SET TRANSACTION READ ONLY;

如果在设置了只读事务的会话里面执行写操作,会报如下错误:

insert into test values(1,'Jack');

 

2.3读类型与隔离级别关系

在 SQL-92 标准中,定义了四种隔离级别:读未提交、读提交、可重复读和串行化。

每种隔离级别下对于读数据有不同的要求。

类别

脏读

不可重复读

幻读

读未提交

Y

Y

Y

读提交

N

Y

Y

可重复读

N

N

Y

串行化

N

N

N

DM 数据库支持三种事务隔离级别:读未提交、读提交和串行化,不支持可重复读。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值