当前位置:首页 » 操作系统 » 数据库死锁

数据库死锁

发布时间: 2022-01-09 01:38:50

数据库中死锁是什么产生的

数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过sql Server 2005, 现在似乎有了一种新的解决办法。

将下面的SQL语句放在两个不同的连接里面,并且在5秒内同时执行,将会发生死锁。

use Northwind
begin tran
insert into Orders(CustomerId) values(@#ALFKI@#)
waitfor delay @#00:00:05@#
select * from Orders where CustomerId = @#ALFKI@#
commit
print @#end tran@#

SQL Server对付死锁的办法是牺牲掉其中的一个,抛出异常,并且回滚事务。在SQL Server 2000,语句一旦发生异常,T-SQL将不会继续运行,上面被牺牲的连接中, print @#end tran@#语句将不会被运行,所以我们很难在SQL Server 2000的T-SQL中对死锁进行进一步的处理。

现在不同了,SQL Server 2005可以在T-SQL中对异常进行捕获,这样就给我们提供了一条处理死锁的途径:

下面利用的try ... catch来解决死锁。

SET XACT_ABORT ON
declare @r int
set @r = 1
while @r <= 3
begin
begin tran

begin try
insert into Orders(CustomerId) values(@#ALFKI@#)
waitfor delay @#00:00:05@#
select * from Orders where CustomerId = @#ALFKI@#

commit
break
end try

begin catch
rollback
waitfor delay @#00:00:03@#
set @r = @r + 1
continue
end catch
end

解决方法当然就是重试,但捕获错误是前提。rollback后面的waitfor不可少,发生冲突后需要等待一段时间,@retry数目可以调整以应付不同的要求。

但是现在又面临一个新的问题: 错误被掩盖了,一但问题发生并且超过3次,异常却不会被抛出。SQL Server 2005 有一个RaiseError语句,可以抛出异常,但却不能直接抛出原来的异常,所以需要重新定义发生的错误,现在,解决方案变成了这样:

declare @r int
set @r = 1
while @r <= 3
begin
begin tran

begin try
insert into Orders(CustomerId) values(@#ALFKI@#)
waitfor delay @#00:00:05@#
select * from Orders where CustomerId = @#ALFKI@#

commit
break
end try

begin catch
rollback
waitfor delay @#00:00:03@#
set @r = @r + 1
continue
end catch
end
if ERROR_NUMBER() <> 0
begin
declare @ErrorMessage nvarchar(4000);
declare @ErrorSeverity int;
declare @ErrorState int;
select
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
raiserror (@ErrorMessage,
@ErrorSeverity,
@ErrorState
);
end

② SQL数据库表的死锁问题

死锁的原因可能有多个。
可能第一个人更新的时候,第二个人尝试读取,第二个人就卡住了。
假如第一个人更新了,还没提交,又去检索一些别的数据,这些数据又是被第三个人锁定的...

SQL Server 多用户之间锁的处理
http://hi..com/wangqing999/blog/item/245768d895cf84b0cc11662b.html
上面这个帖子演示一个 多用户数据锁定 / 死锁 的例子.

C# 多线程处理 IV 线程安全
http://hi..com/wangqing999/blog/item/6c40f05df135e83a2834f0fc.html
这个帖子,提供一个 C# 中,如果通过同步处理, 确保某个 资源,在一个时间点上,只有一个用户可以使用的例子。

③ 数据库死锁怎么处理

可以用 sp_who 'active' 看一下午 blk 字段是否为 0 ,如是其它数x,说明这个数可能就是锁,再用 sp_who 数x 看一下它下面的 blk 是否有数,这样查下去,如果它下面没有数并且是查询状态或是等待状态等(除更新及插入状态)都可以用 kill 数x

④ 怎么查看数据库死锁,和解决方法

exec sp_lock 快捷键 C_2
exec sp_who active exec sp_who快捷键 C_1
用Profiler里面的Locks->Deadlock graph 监控看看,如果看到了死锁图,就可以比较形象地展现死锁发生的过程,还可以看到锁的具体类型和过程里面的语句,对你诊断会有帮助。

Declare @LockTab table( spid int,dbid int ,ObjId int,IndId int ,Type varchar(50),Resource varchar(50),Mode varchar(50),Status varchar(50))
insert into @LockTab exec sp_lock
Declare @ActiveTab table(spid int,ecid int,status varchar(50),loginname varchar(50),hostname varchar(50),blk int,dbname varchar(50),cmd varchar(50),request_id int)
insert into @ActiveTab exec sp_who active
select * from @LockTab lt
left join @ActiveTab at on lt.spid=at.spid

⑤ 数据库死锁,怎样解决

^_^什么数据库啊oracle的就用楼上的就可以了很详细不过要用sysdba这个权限级别的用户才可以的,其他的还真不知道呢

⑥ oracle数据库死锁怎么解决

Oracle数据库出现死锁的时候可以按照以下处理步骤加以解决:

第一步:尝试在sqlplus中通过sql命令进行删除,如果能够删除成功,则万事大吉!但通常情况下,出现死锁时,想通过命令行或者通过Oracle的管理工具删除有死锁的session,oracle只会将该session标记为killed,但无法清除掉,往往需要通过第二步在操作系统层级进行删除!

.2.0.1.0
Connectedasquik
SQL>selectxisn,object_id,session_id,locked_modefromv$locked_object;--查死锁的对象,获取其SESSION_ID
XIDUSNOBJECT_IDSESSION_IDLOCKED_MODE
-----------------------------------------
1030724293
1030649293
SQL>selectusername,sid,serial#fromv$sessionwheresid=29;--根据上步获取到的sid查看其serial#号
USERNAMESIDSERIAL#
--------------------------------------------------
QUIK2957107
SQL>altersystemkillsession'29,57107';--删除进程,如已经删除过,则会报ora-00031的错误;否则oracle会将该session标记为killed状态,等待一段时间看能否会自动消失,如长时间消失不掉,则需要做后续步骤
altersystemkillsession'29,57107'
ORA-00031:sessionmarkedforkill
SQL>selectpro.spidfromv$sessionses,v$processprowhereses.sid=29andses.paddr=pro.addr;--查看spid号,以便在操作系统中根据该进程号删除进程
SPID
------------
2273286

第二步:进入操作系统进行删除进程,本示例的操作系统是IBM aix。

login:root--录入用户名
root'sPassword:--录入密码
*******************************************************************************
**
**
*WelcometoAIXVersion5.3!*
**
**
*PleaseseetheREADMEfilein/usr/lpp/bosforinformationpertinentto*
*.*
**
**
*******************************************************************************
Lastunsuccessfullogin:FriApr2314:42:57BEIDT2010on/dev/pts/1from10.73
.52.254
Lastlogin:FriApr2315:27:50BEIDT2010on/dev/pts/2from10.73.52.254
#ps-ef|grep2273286--查看进程详情
root22898642494636017:07:15pts/10:00grep2273286
oracle22732861014:38:24-0:21oracleQUIK(LOCAL=NO)
#kill-92273286--删除进程,小心操作,别写错进程号,如果oracle的关键进程被删,数据库会崩溃的!
#ps-ef|grep2273286--再次查看
root22898642494636017:07:15pts/10:00grep2273286
ForWindows,attheDOSPrompt:orakillsidspid
ForUNIXatthecommandline>kill–9spid

⑦ 数据库死锁一般都什么原因导致的

简单讲:比如,在同一表中,你在编辑A记录,我访问和修改B记录,此时两个记录都被锁定。
然后,在同一时时,您要释放A记录,进入编辑B记录,而我要释放B记录进入编辑A记录。
这样,死锁就形成了。您不能进入被我锁定的B记录,从而继续停留在A记录。我不能进入正被您锁定的A记录,从而继续留在B记录。互相等待对方释放锁定的记录,而不能释放自已所在的记录,从而无限期等待。

⑧ 数据库为什么总是产生死锁

多线程是很容易造成死锁,一般情况下死锁都是因为并发操作引起的。我不懂JAVA,但死锁这个问题每种开发工具和数据库都会碰到.解决办法是:
1、程序方面优化算法(如有序资源分配法、银行算法等),在一个程序里,能不用多线程更新同一张数据库表 尽量不要用,如果要用,其避免死锁的算法就很复杂。
2、数据库方面设置等待超时时间
3、发生死锁后直接KILL掉数据库进程

⑨ 数据库死锁处理方法

mysql数据库死锁解决方法如下:

1、对于按钮等控件,点击后使其立刻失效,不让用户重复点击,避免对同时对同一条记录操作。

2、使用乐观锁进行控制。乐观锁大多是基于数据版本(Version)记录机制实现。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是 通过为数据库表增加一个“version”字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数 据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。乐观锁机制避免了长事务中的数据 库加锁开销(用户A和用户B操作过程中,都没有对数据库数据加锁),大大提升了大并发量下的系统整体性能表现。Hibernate 在其数据访问引擎中内置了乐观锁实现。需要注意的是,由于乐观锁机制是在系统中实现,来自外部系统的用户更新操作不受系统的控制,因此可能会造 成脏数据被更新到数据库中。

热点内容
实测华为编译器 发布:2024-09-19 23:50:52 浏览:821
linux汇总 发布:2024-09-19 23:46:39 浏览:452
阿里云服务器环境搭建教程 发布:2024-09-19 23:21:58 浏览:837
黄色文件夹图标 发布:2024-09-19 23:19:22 浏览:684
mysql数据库导出导入 发布:2024-09-19 23:00:47 浏览:183
lua脚本精灵 发布:2024-09-19 23:00:41 浏览:659
任务栏文件夹图标 发布:2024-09-19 22:54:25 浏览:101
解压来一波 发布:2024-09-19 22:46:36 浏览:933
mysqlpythonubuntu 发布:2024-09-19 22:46:27 浏览:501
服务器请求获取ip地址 发布:2024-09-19 22:33:25 浏览:515