ORACLE数据库并发

目录

概述

数据库并发带来的问题

脏读

不可重复读

幻读

事务

事务的产生

事务的特性

事务的隔离级别

Oracle支持的事务隔离级别

锁机制

锁类型

锁冲突与死锁

死锁的查询与解决

总结


概述

        数据库并发,其实就是多个事务同时操作数据库。通过事务自身的特性,来保障数据库的一致性和完整性。但不可避免的,数据库并发时还是会产生问题。除了不可重复读、幻读这些问题外;多个事务争抢资源时产生的死锁甚至会影响到生产。所以数据库并发的管理是非常重要的。

数据库并发带来的问题

        数据库并发可能会带来脏读、不可重复读、幻读等问题,以下表格是几种问题的汇总,表格是曾经读大学时Oracle数据库教材中的,但认为现在这个也不过时。

并发问题
隔离级别脏读可能性不可重复读可能性幻读可能性Oracle支持隔离级别
未提交读否        
一致性读
重复读否                            
串行读

脏读

一个事务读取到了另一个事务尚未提交的数据。Oracle的隔离级别不会出现此问题。

不可重复读

在一个事务中,读取了两次同一行数据,但每次读取出来的结果不一致。比如:一个事务中发生多次相同的查询语句,但在此期间,因为其他事务提交了对所查询语句的修改或者删除,导致每次查询结果不同。Oracle的隔离级别会发生此问题

幻读

在一个事务中发生多次相同的查询语句,由于其他事务提交了所做的insert操作,虽然查询条件相同,但是查询结果却不同。Oracle的隔离级别会发生此问题。

总结:

Oracle不会发生脏读;

不可重复读和幻读的区别在于一个是读到了更新删除的数据,一个是读到了插入的数据。

事务

        什么是事务?官方给出的描述是“事务是工作的逻辑单元,一个事务由一个或者多个完成一组相关行为的SQL语句组成;通过事务机制确保这一组SQL语句做的操作要么完全成功执行,要么彻底不执行,或者什么都不做”。

        通俗的讲,把数据库从一种状态改变到另一种状态,这就是事务。

事务的产生

以下SQL会产生事务

1、DML语句

INSERT、DELETE、UPDATE、MERGE

2、DDL语句

ALTER CREATE、DROP

3、DCL语句

GRANT、REVOKE

事务的特性

1、原子性

听着有点教条;通俗解释说就是一个事务要么提交,要么回滚;用来保证数据库的一致性

2、一致性

数据库在事务操作前和事务操作后,数据库中的数据必须保持状态一致。

3、隔离性

数据库允许多个并发的事务,同时对数据进行读写和修改。隔离性可以防止多个事务并发时,由于操作命令的交叉导致的数据的不一致的情况,使得两个事务互不干扰。

4、持久性

事务处理结束后,它对数据的修改应该是永久的。即便是系统遇到故障,也不会丢失。

在当初学习OCP时,老师讲过事务的特性记住ACID(Atomicity、Consistency、Isolation、Durability);如果英语好,记这个更好。

事务的隔离级别

事务的隔离级别分为4种:

1、未提交读(read uncommitted)

一个事务可以读到另一个事务未提交的数据(INSERT、UPDATE、DELETE)。

2、提交读或者一致性读(read committed)

一个事务需要等到另一个事务提交后才能读取到已提交事务发生操作的数据(INSERT、UPDATE、DELETE)。

3、重复读(repeat read)

数据读出来后加锁,不让其他事务修改这部分读出来的数据。

4、串行化(serlilizable)

最高的事务隔离级别,不管有多少个事务,都是挨个运行,做完一个事务或者其所有子事务后才可以执行另外一个事务及其所有子事务。(但是串行化隔离级别的缺陷也很明显,就是数据库性能降低)

Oracle支持的事务隔离级别

1、提交读(一致性读)

切换到一致性读隔离模式:

Set transaction isolation level read committed

2、串行化

切换到串行化隔离模式

Set transaction isolation level serializable

3、read only

切换到只读模式:

Set transaction read only

4、read write

切换到读写正常模式

Set transaction read write

发生事务时,锁会自动获得。锁是为了防止多个会话同时更改同一行数据。

锁机制

1、高级别的数据并发场景下

(1)查询不需要锁;

(2)行级锁用于增删改等操作

(3)表级锁先于行级锁发生

(4)select ... from table_name [where xxxx] for update 会产生行锁

2、自动队列管理

(1)锁遵循先进先出的原则。A、B、C3个事务去修改同一行数据时;最先发生的事务A先抢占到资源,此时这一行数据被上锁。只有当事务A提交或回滚后,这一行上的锁被释放,然后时间顺序第二发生的事务B拿到该资源,再次对这一行数据上锁;事务B提交或回滚后,事务C最后拿到该资源进行修改。

3、保持锁定直到事务结束

锁类型

DML锁

1、TX锁(行级锁/事务锁)

当一个事务发起一个DML语句时,就会获得一个TX锁,该锁保持到事务结束。

2、TM锁(表级锁)

        当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再自动申请TX类型的锁,并将实际锁定的数据行的锁标志位进行置位。这样在事务加锁前检查TX锁的相容性时就不用再逐行检查锁标志,只需要检查TM锁模式的相容性即可,提高了系统的效率。不同的SQL操作会产生不同类型的锁。

锁冲突与死锁

         锁冲突与死锁并不是等价的。根据个人所遇到的情况,认为可以将其理解为死锁是锁冲突的一种特殊情况。

        两个或两个以上的事务在进行操作时,事务1事务2修改同一行数据时。如果是因为事务2执行时间较长,或者忘记提交或回滚,就会造成锁冲突。如果是因为争抢资源造成的互相等待,在没有外力的干预下,就会形成死锁,数据库会报“ORA-00060”错误。

        如下图所示,是锁冲突与死锁的产生情况:

锁冲突与死锁

死锁的查询与解决

        网上查杀死锁的方法有很多,查杀SQL也很多样,以下只是其中一种查杀方式,是根据个人喜好所编写的,看官可以根据自己的习惯改写。

        这里主要是是用了Oracle的树形查询与SYS_CONNECT_BY_PATH函数;该函数可以将父节点到当前行的内容以“路径”或者层次的形式显示出来,可以清晰的发现锁源头,进而进行查杀。

SELECT
se.inst_id,
se.process,
se.sid,
se.serial#,
se.event,
se.status,
se.machine,
CONNECT_BY_ISLEAF AS isleaf,
SYS_CONNECT_BY_PATH(se.sid || '@' || se.inst_id,'<-') AS tree,
LEVEL AS tree_level,
DECODE(CONNECT_BY_ISLEAF,1,'alter system kill session '''|| sid || ',' || serial# || ',@' || se.inst_id || ''' immediate;' ) AS kill_txt,
sq.sql_text
FROM gv$session se
LEFT JOIN v$sql sq on sq.sql_id = se.sql_id
START WITH se.blocking_session IS NOT NULL
CONNECT BY (se.sid || '@' || se.inst_id) = PRIOR
                      (se.blocking_session || '@' || se.blocking_instance)
运行结果
alter system kill session '70,4725,@1' immediate;

参数说明:

inst_id:会话所在的节点号

process:客户端进程号(可以在自己本机打开任务进程详细信息比对以下,与v$process的PID不是同一个)

sid:会话标识符

serial#:会话序列号

event:等待事件的名称,若空,表示ON CPU

status:会话的状态(ACTIVE:当前正在执行SQL语句、INACTIVE:等待操作(等待需要执行的SQL)、KILLED:标记为终止删除、CACHED:为Oracle*XA使用临时高速缓存、SNIPED:会话不活动,在客户机上等待,该状态不再允许变为ACTIVE)

machine:操作系统机器名

connect_by_isleaf:是否源头(0代表否,1代表是)

tree:树形结构,锁的层次。如运行结果所示,<-71@1<-70@1,从左到右依次表示为节点1的会话71被节点1的会话70堵塞,所以节点1会话70是锁的源头

tree_level:树形层次

kill_txt:杀死锁语句

sql_text:对应的SQL语句

总结

平时大家都遇到过一群人争抢着做一件事的情况;

运用合理的制度和手段去解决争抢过程中带来的问题是最重要的;

数据库并发与此类似,理解清楚概念后,解决并发带来的问题及影响才是最重要的,也就是需要及时合理的解决数据库死锁问题。

  • 32
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姜豆豆耶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值