在oracle数据库中一般什么情况下会产生死锁,一般又是如何解决的呢

在oracle数据库中一般什么情况下会产生死锁,一般又是如何解决的呢,第1张

例子?

事务A 事务B

时间点C 请求排他锁A 请求排他锁B

时间点D 请求排他锁B 请求排他锁A

这是个环路等待的例子吧,结局是事务A一致等锁B的释放,而事务B一致等锁A的释放

解决的方法 是 重写代码,2个锁一起请求,而不是分开请求

阻塞只是因为事务没有执行完成而锁住相关的资源而导致其它事务不能访问被锁住的资源。

死锁是这样:

事务1 先请求 A,再请求B

事务2 先请求B,再请求A 这样,就会造成死锁

导致

死锁

的主要原因是

SQL语句

里有for

update

导致。比如当你访问这个表时候

有人使用了for

update进行

数据修改

,那在你那里调试也好执行也好

都会导致无法返回结果

一直卡在那里。

1151 锁的概念

锁(Lock) 是在多用户环境下对资源访问的一种限制。机制当对一个数据源加锁后,此数据源就有了一定的访问限制。我们就称对此数据源进行了“锁定”。在SQL Server中,可以对以下的对象进行锁定:

数据行(Row):数据页中的单行数据;

索引行(Key):索引页中的单行数据,即索引的键值;

页(Page):页是SQL Server 存取数据的基本单位,其大小为8KB;

盘区(Extent):一个盘区由8 个连续的页组成;

表(Table);

数据库(Database)。

1152 锁的类别

在SQL Server 中,锁有两种分类方法。

(1) 从数据库系统的角度来看

锁分为以下三种类型:

独占锁(Exclusive Lock)

独占锁锁定的资源只允许进行锁定 *** 作的程序使用,其它任何对它的 *** 作均不会被接受。执行数据更新命令,即INSERT、 UPDATE 或DELETE 命令时,SQL Server 会自动使用独占锁。但当对象上有其它锁存在时,无法对其加独占锁。独占锁一直到事务结束才能被释放。

共享锁(Shared Lock)

共享锁锁定的资源可以被其它用户读取,但其它用户不能修改它。在SELECT 命令执行时,SQL Server 通常会对对象进行共享锁锁定。通常加共享锁的数据页被读取完毕后,共享锁就会立即被释放。

更新锁(Update Lock)

更新锁是为了防止死锁而设立的。当SQL Server 准备更新数据时,它首先对数据对象作更新锁锁定,这样数据将不能被修改,但可以读取。等到SQL Server 确定要进行更新数据 *** 作时,它会自动将更新锁换为独占锁。但当对象上有其它锁存在时,无法对其作更新锁锁定。

(2)从程序员的角度看

锁分为以下两种类型:

乐观锁(Optimistic Lock)

乐观锁假定在处理数据时,不需要在应用程序的代码中做任何事情就可以直接在记录上加锁、即完全依靠数据库来管理锁的工作。一般情况下,当执行事务处理时SQL Server会自动对事务处理范围内更新到的表做锁定。

悲观锁(Pessimistic Lock)

悲观锁对数据库系统的自动管理不感冒,需要程序员直接管理数据或对象上的加锁处理,并负责获取、共享和放弃正在使用的数据上的任何锁。

1153 隔离级别

隔离(Isolation) 是计算机安全学中的一种概念,其本质上是一种封锁机制。它是指自动数据处理系统中的用户和资源的相关牵制关系,也就是用户和进程彼此分开,且和 *** 作系统的保护控制也分开来。在SQL Server 中,隔离级(Isolation Level) 是指一个事务 和其它事务的隔离程度,即指定了数据库如何保护(锁定)那些当前正在被其它用户或服务器请求使用的数据。指定事务的隔离级与在SELECT 语句中使用锁定选项来控制锁定 方式具有相同的效果。

在SQL Server 中有以下四种隔离级:

READ COMMITTED

在此隔离级下,SELECT 命令不会返回尚未提交(Committed) 的数据,也不能返回脏数据。它是SQL Server 默认的隔离级。

READ UNCOMMITTED

与READ COMMITTED 隔离级相反,它允许读取已经被其它用户修改但尚未提交确定的数据。

REPEATABLE READ

在此隔离级下,用SELECT 命令读取的数据在整个命令执行过程中不会被更改。此选项会影响系统的效能,非必要情况最好不用此隔离级。

SERIALIZABLE

与DELETE 语句中SERIALIZABLE 选项含义相同。

隔离级需要使用SET 命令来设定其语法如下:

SET TRANSACTION ISOLATION LEVEL

{READ COMMITTED

| READ UNCOMMITTED

| REPEATABLE READ

| SERIALIZABLE }

1154 查看锁

可以通过企业管理器或存储过程来查看锁。

(1) 用Enterprise Manager 查看锁

在企业管理器中选择目录树窗口中“Management” 文件夹下,“Current Activity” 中的“Locks / Process ID” 节点,则可以查看当前锁定的进程;选择同级的“Locks / Object”节点下的相应字节点,则可以查看当前锁定的对象,如图11-1 所示。在图11-1 中,右键单击任务板窗口中的对象,从快捷菜单中选择“属性”选项,则会出现如图11-2 所示的锁的进程细节对话框。在此,可以刷新或杀死锁的进程。

杀死进程还可以用如下Transact-SQL 命令来进行:

KILL spid

spid 是System Process ID, 即系统进程编号的缩写,如图11-1 中所示。

图11-2 锁定的进程细节

(2) 用系统存储过程Sp_lock 查看锁

存储过程Sp_lock 的语法如下:

sp_lock spid

SQL Server 的进程编号spid 可以在masterdbosysprocesses 系统表中查到。spid 是INT类型的数据,如果不指定spid ,则显示所有的锁。

1155 死锁及其防止

死锁(Deadlocking) 是在多用户或多进程状况下,为使用同一资源而产生的无法解决的争用状态,通俗地讲,就是两个用户各占用一个资源,两人都想使用对方的资源,但同时又不愿放弃自己的资源,就一直等待对方放弃资源,如果不进行外部干涉,就将一直耗下去。

死锁会造成资源的大量浪费,甚至会使系统崩溃。在SQL Server 中解决死锁的原则是“牺牲一个比两个都死强”,即挑出一个进程作为牺牲者,将其事务回滚,并向执行此进程的程序发送编号为1205 的错误信息。而防止死锁的途径就是不能让满足死锁条件的情况发生,为此,用户需要遵循以下原则:

尽量避免并发地执行涉及到修改数据的语句;

要求每个事务一次就将所有要使用的数据全部加锁,否则就不予执行;

预先规定一个封锁顺序所有的事务,都必须按这个顺序对数据执行封锁,例如,不同的过程在事务内部对对象的更新执行顺序应尽量保持一致;

每个事务的执行时间不可太长,对程序段长的事务可考虑将其分割为几个事务。

本章小结

本章中介绍了数据更新的方法及事务和锁的概念。除了使用本章讲述的语句更新数据外,还可以使用视图来更新数据,有关视图的运用请参见第13 章“游标和视图”。

数据库中解决死锁的常用方法有: (1)要求每个事务一次就将所有要使用的数据全部加锁,否则就不能执行。

(2)采用按序加锁法。

(3)不采取任何措施来预防死锁的发生,而是周期性的检查系统中是否有死锁。

多线程是很容易造成死锁,一般情况下死锁都是因为并发 *** 作引起的。我不懂JAVA,但死锁这个问题每种开发工具和数据库都会碰到解决办法是:

1、程序方面优化算法(如有序资源分配法、银行算法等),在一个程序里,能不用多线程更新同一张数据库表 尽量不要用,如果要用,其避免死锁的算法就很复杂。

2、数据库方面设置等待超时时间

3、发生死锁后直接KILL掉数据库进程

以上就是关于在oracle数据库中一般什么情况下会产生死锁,一般又是如何解决的呢全部的内容,包括:在oracle数据库中一般什么情况下会产生死锁,一般又是如何解决的呢、数据库阻塞和死锁的区别、数据库查询发生死锁等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9289771.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存