达梦数据库------封锁机制
锁的定义与作用
定义:通过数据库支持多用户并发 控制
作用:保持数据的一致性 与正确性
封锁机制
乐观锁、悲观锁是并发控制的核心思想
乐观锁
默认不会发生并发冲突,因此操作数据前不加锁 ,仅在提交事务时,通过 "版本校验" 判断数据是否被其他事务修改,若已修改则放弃操作并回滚,若未修改则提交。
悲观锁
默认会发生并发冲突,因此操作数据前,对数据加锁 ,强制独占访问,直到操作完成才释放锁,从根源上避免冲突。
悲观锁的模式分类
共享锁
share lock 简称s锁
定:用于读操作,事务可并发读取相同资源,不允许任何事务修改。
相关命令:
bash
/*设置共享模式*/
LOCK TABLE staff in SHARE mode;
排他锁
exclusive lock 简称x锁
定:用于写操作,独占,不允许任何其他事务访问被封锁对象
相关命令:
sql
/*设置排他模式*/
LOCK TABLE staff in EXCLUSIVE mode;
意向锁
用于读取与修改数据时使用,可同时对相同对象上锁
- IS 意向共享锁:只读访问使用,可看可修(任意一边)
sql
/*设置意向共享模式*/
LOCK TABLE staff in intent SHARE mode;
- IX 意向排他锁:修改数据时使用,但是不能修改同一条数据(就是只有加ix锁的一边可修改)
sql
/*设置意向排他模式*/
LOCK TABLE staff in intent EXCLUSIVE mode;
各个锁是否相容表
Y代表相容;X代表不相容
| S | X | IS | IX | |
|---|---|---|---|---|
| S | Y | X | Y | X |
| X | X | X | X | X |
| IS | Y | X | Y | Y |
| IX | X | X | Y | X |
根据封锁对象分类
TID对象(行锁):以事务号(ID)为封锁对象
对象锁:以对象ID为封锁对象
事务隔离级别
隔离级别:读提交、读未提交,可重复读、串行化
但在达梦数据中只有读提交、读未提交、串行化三种隔离级别
查看隔离级别:
sql
select id,isolation from V$TRX;
注:isolation
0表示读未提交 1表示读提交 3表示串行化,可重复读
设置隔离级别为读提交
sql
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
设置隔离级别为读未提交
sql
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
设置隔离级别为可重复读
sql
SET TRANSACTION ISOLATION LEVEL repeatable READ;
设置隔离级别为串行化
sql
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
优点以及缺点
- 读提交最大限度支持并发性能,发生无不可重复读与幻象读
- 读未提交情况下,在此级别下,我啥都能发生,是最不严格的隔离级别,发生脏读
- 串行化级别下,无不可重复读与幻象读现象,但并发能力弱喔
在事务隔离级别可发生以下现象
脏读
定:已经修改,但未提交的数据,另外一个事务可看到修改数据
不可重复读
为读提交
定:DM默认事务隔离级别,读取同一数据,两次读取数据不同
幻象读
为读提交
定:发现其他事务插入的新数据或者是删除的数据,一会有一会没有
扩展
死锁与活锁
活锁:可变
死锁:n个事务争夺n-1个进程或者更少,即锁死。
解决方法:杀进程
步骤:
- 看sql_text对应的id
bash
select * from v$sessions;
- 杀进程
bash
Sys.sp_close_sessoin(id);
涉及到的语句:
sql
set SCHEMA sch_factory;
/*查看上下文*/
SELECT SYS_CONTEXT('userenv','current_schema');
/*查看数据库对象*/
SELECT * from DBA_OBJECTS WHERE OBJECT_NAME='STAFF';
/*查看锁 ltype 是对象锁*/
SELECT * from SYS.V$LOCK WHERE TABLE_ID=1025;
SELECT * from SYS.V$LOCK ;
SELECT * FROM STAFF;
/*设置共享模式*/
LOCK TABLE staff in SHARE mode;
/*设置排他模式*/
LOCK TABLE staff in EXCLUSIVE mode;
/*设置意向共享模式*/
LOCK TABLE staff in intent EXCLUSIVE mode;
/*事务ID,有id就有了*/
SELECT * from SYS.V$TRX;
/*作更新*/
UPDATE staff SET 年龄=40 where 职工号=3012;
/*设置隔离级别为读提交*/
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
/*设置隔离级别为读未提交*/
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
/*查看隔离级别*/
select id,isolation from V$TRX;
/*试图在事务运行中,改变其属性-隔离级别rollback*/
rollback;
/*设置隔离级别为可重复读*/
SET TRANSACTION ISOLATION LEVEL repeatable READ;
/*设置隔离级别为串行化*/
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;