事务和锁机制
1. 事务的四⼤特性
1.1原⼦性
即不可分割性,事务要么全部被执⾏,要么全部不被执⾏,⼀个事务包含的操作要么全部执⾏成功,要么全部执⾏失败。
1.2⼀致性
事务的执⾏使数据库从⼀种正确状态转换成另⼀种正确状态。
1.3隔离性
在事务正确提交之前,不允许把该事物对数据的任何改变提供给任何其他事务。
1.4永久性
事务正确提交后,其结果将永久的保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。
1. 提交事务的模式
提交事务就是提交事务对数据库所做的修改,将从事务开始的所有更新保存到数据库
中,任何更改的记录都被写⼊⽇志⽂件并最终写⼊到数据⽂件,同时提交事务还会释放由事
务占⽤的资源,如锁。
2.1⾃动提交模式
除了命令⾏交互式⼯具 DISQL 外,DM 数据库缺省都采⽤⾃动提交模式。
Disql设置⾃动提交模式命令:
set autocommit on;
注:此命令并⾮永久性改为⾃动提交,当会话终⽌,重新登录disql时,需重新执⾏此命令
2.2⼿动提交模式
在⼿动提交模式下,DM 数据库⽤户或者应⽤开发⼈员明确定义事务的开始和结束,这
些事务也被称为显式事务。在 DISQL 中,没有设置⾃动提交时,就是处于⼿动提交模式。
2.3隐式提交
在⼿动提交模式下,当遇到 DDL 语句时,DM 数据库会⾃动提交前⾯的事务,然后开始⼀个新的事务执⾏ DDL 语句。这种事务提交被称为隐式提交。
1. 事务的回滚
回滚事务是撤消该事务所做的任何更改。回滚有两种形式:DM 数据库⾃动回滚,或者
通过命令rollback⼿动回滚。
3.1⾃动回滚
若事务运⾏期间出现连接断开,DM 数据库都会⾃动回滚该连接所产⽣的事务。回滚会
撤消事务执⾏的所有数据库更改,并释放此事务使⽤的所有数据库资源。DM 数据库在恢复
时也会使⽤⾃动回滚。
3.2⼿动回滚
当某条 SQL 语句执⾏失败时,使⽤ ROLLBACK 语句或者编程接⼝提供的回滚函数来回滚整个事务,避免不合逻辑的事务污染数据库,导致数据不⼀致。
3.3回滚到保存点
如果发⽣错误后确实只⽤回滚事务中的⼀部分,则需要⽤到回滚到保存点的功能,即从事务的最末端回滚到事务中任意⼀个被称为保存点的标记处,⼀个事务中可以创建多个保存点。
创建保存点:
通过savepoint语句定义⼀个保存点。
语法:
savepoint  savepoint_name;
回滚到保存点
通过使⽤ rollback to  savepoint_name 回滚到指定的保存点。
3.4语句级回滚
如果在⼀个 SQL 语句执⾏过程中发⽣了错误,此语句对数据库产⽣的影响将被回滚,
回滚后就如同此语句从未执⾏过,这种操作被称为语句级回滚。语句级回滚只会使此语句所
做的数据修改⽆效,不会影响此语句之前所做的数据修改。
1. 事务锁
4.1锁模式
1.共享锁(S)
⽤于读操作,防⽌其他事务修改正在访问的对象。
s锁允许多个事务同时读取相同的资源,但是不允许任何事务修改这个资源。
2.排它锁(X)
⽤于写操作,以独占的⽅式访问对象,不允许任何其他事务访问被封锁对象;防⽌多个事务同时修改相同的数据,避免引发数据错误,防⽌其他事务访问⼀个正在修改的对象,避免数据不⼀致。
3.意向锁
意向锁(Intent Lock)⽤于读取或修改被访问对象数据时使⽤,多个事务可以同时
对相同对象上意向锁,DM ⽀持两种意向锁:
意向共享锁(IS)提交更改是内存条吗
⼀般在只读访问对象时使⽤;
不允许其他事务独占修改该表。意向共享锁定后,不同事务可以同时增、删、改、查该表的数据,也⽀持在该表上创建索引,但不⽀持修改该表的定义。
意向排它锁(IX)
⼀般在修改对象数据时使⽤;
不允许其他事务独占访问和独占修改该表。被意向排他后,不同事务可以同时增、删、改、查该表的数据,不⽀持在该表上创建索引,也不⽀持修改该表定义。
4.2锁粒度
按照封锁对象的不同,锁可以分为 TID 锁和对象锁。
1.TID锁
数据库每⼀⾏记录隐含⼀个TID字段,⽤于事务可见性判断。执⾏ insert delete update操作时,设置事务的事务号到TID字段,会隐式地为该⾏上TID锁。
同⼀事务的增删改,不会导致对该⾏重新加锁,提升了性能。
不同事务操作相同⾏时,第⼆个事务会加锁,其锁对象为第⼀个事务的TID号。
DM使⽤多版本并发控制机制,因此不再存在⾏锁的概念。
2.对象锁
DM取消了传统数据库的数据字典锁和表锁,引⼊对象锁⽤以减少事务冲突,提升并发性能。为提供与表锁同样的功能,从逻辑上将对象锁的动作分为四类:
1.独占访问(EXCLUSIVE ACCESS),不允许其他事务修改对象,不允许其他事务访问对象,使⽤ X ⽅式封锁
2.独占修改(EXCLUSIVE MODIFY),不允许其他事务修改对象,允许其他事务共享访问对象,使⽤ S + IX ⽅式封锁
3.共享修改(SHARE MODIFY),允许其他事务共享修改对象,允许其他事务共享访问对象,使⽤ IX ⽅式封锁
4.共享访问(SHARE ACCESS),允许其他事务共享修改对象,允许其他事务共享访问对象,使⽤ IS ⽅式封锁
3.显⽰锁定表
⽤户可以根据⾃⼰的需要显式的对表对象进⾏封锁。显式锁定表的语法如下:
LOCK TABLE <table_name> IN <lock_mode> MODE [NOWAIT];
Lock_mode的取值:
SHARE    加共享锁
EXCLUSIVE 加排它锁
INTENT SHARE 意向共享锁
INTENT EXCLUSIVE 意向排它锁
参数nowait,若提供,则表⽰对表加锁时若不能⽴即上锁,就返回加锁失败错误。
4.3查看锁
命令:
select * from v$lock;
列含义
字段含义
ADDR表⽰锁的内存地址
TRX_ID表⽰锁所属的事务 ID
LTYPE表⽰锁的类型,OBJECT(对象锁)或者 TID(TID 锁)
LMODE锁的模式,S(共享锁)X(排他锁)IS(意向共享锁)IX(意向排它锁)
BLOCKED表⽰锁是否处于上锁等待状态(0表⽰上锁成功,1处于上锁等待状态)
TABLE_ID对于对象锁,表⽰表对象或字典对象的 ID,对于 TID 锁,表⽰封锁记录对应的表 ID
ROW_IDX TID 锁封锁记录的⾏信息
TID TID 锁对象事务 ID
4.4阻塞和死锁
1.阻塞
insert产⽣阻塞原因:当多个事务同时试图向有主键或UNIQUE约束的表中插⼊相同的数据时,前⼀个事务未提交,后⾯的事务将被阻塞,直到前⼀个事务提交或回滚。
update和delete产⽣阻塞原因:操作执⾏时,如果有别的事务正在对操作的⾏进⾏相同类型的操作,则在别的事务提交,或者回滚前,操作⼀直会阻塞。
2.死锁
死锁与阻塞的不同之处在于死锁包括两个或者多个已阻塞事务,它们之间形成了等待环,每个都等待
其他事务释放锁。
例如事务1给表T1上了排他锁,第⼆个事务给表T2上了排他锁,此时事务1请求T2的排他锁,就会处于等待状态,被阻塞。若此时T2再请求表T1的排他锁,则T2也处于阻塞状态。此时这两个事务发⽣死锁,DM数据库会选择牺牲掉其中⼀个事务。
4.5锁等待解决⽅法
1. 获取表id
select name, id from sysobjects where name = '表名';
注:此命令的表名需要⼤写
1. 查询处于等待的锁
⽅法⼀:
select TRX_ID, LTYPE, LMODE, BLOCKED, BLOCKED TABLE_ID, TID from v$lock where table_id = 表的id;
例:
BLOCKED为1是处于上锁等待状态
⽅法⼆:
Select * from v$trxwait;
例:
1. 根据事务id到会话id
select sess_id, sql_text, trx_id from v$sessions where trx_id=10035;
例:
1. 通过会话id结束会话sp_close_session(会话id);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。