日期:2014-05-16  浏览次数:21108 次

使用游标时如何避免死锁
在数据库里创建了一个 定时服务,每隔5秒就执行一个存储过程,存储过程会用到游标去执行另一个存储过程,这个存储过程涉及到几表,会有一些 update,select,insert动作,

这样是不是很容易会死锁?怎么避免?能够改变锁的范围吗,只锁定某一行的数据?
------最佳解决方案--------------------
引用:
引用:
表现为事务锁

请问 我的存储是不是要加上 事务?

oracle不需要显式的begin transaction....,所以一般情况下是不需要的,除非你有很特殊的业务需求。只需要在做完后commit/rollback就可以了
------其他解决方案--------------------
很容易发生死锁,死锁发生的原因是你执行间隔时间有点短,如果上一个存储过程还没有执行完毕的话,下个过程又开始执行,就会发生死锁,看你的情况,存储过程执行的操作似乎比较多,请确认5秒钟之内能够执行完毕?
------其他解决方案--------------------
死锁发生的可能性很小的。oracle自动在DML操作行上加锁
------其他解决方案--------------------
引用:
在数据库里创建了一个 定时服务,每隔5秒就执行一个存储过程,存储过程会用到游标去执行另一个存储过程,这个存储过程涉及到几表,会有一些 update,select,insert动作,

这样是不是很容易会死锁?怎么避免?能够改变锁的范围吗,只锁定某一行的数据?

对于程序员而言,如果你作到了事务正常/异常结束后,进行了commit/rollback,剩下的死锁问题就由Oracle解决。在上述前提下,对于Oracle而言,死锁的概率还是非常小的。通常死锁的情形是两种:(1)没有commit/rollback。(2)在一个长事务中,不能commit/rollback。对于后一种情形,程序员应该尽量设法避免。

锁的粒度是RDBMS决定的。Oracle提供行级锁。如果你的update只更新一条记录,基本就是使用的行级锁。

死锁通常发生在两个独立的进程/线程之间,准确的说是两个事务之间,和是否使用存储过程嵌套、是否使用游标没有关系,有关系的只是事务完成的时间(忘记commit/rollback的本质就是事务变成了一个长事务而已)。

因此,避免Oracle死锁两个主要手段:
(1)尽量设计短事务
(2)记得commit/rollback

------其他解决方案--------------------
引用:
引用:
在数据库里创建了一个 定时服务,每隔5秒就执行一个存储过程,存储过程会用到游标去执行另一个存储过程,这个存储过程涉及到几表,会有一些 update,select,insert动作,

这样是不是很容易会死锁?怎么避免?能够改变锁的范围吗,只锁定某一行的数据?

对于程序员而言,如果你作到了事务正常/异常结束后,进行了commit/rollback,剩下的死锁问题就由O……

我的存储过程没有使用 事务
------其他解决方案--------------------
你的这些过程、游标都属于同一个事务,怎么可能发生死锁?除非他们中有自治事务
------其他解决方案--------------------
引用:
你的这些过程、游标都属于同一个事务,怎么可能发生死锁?除非他们中有自治事务

如果 存储在执行时,刚刚有他人也在同时对那些表进行操作,这样会发生死锁吗?
------其他解决方案--------------------
引用:
引用:
你的这些过程、游标都属于同一个事务,怎么可能发生死锁?除非他们中有自治事务

如果 存储在执行时,刚刚有他人也在同时对那些表进行操作,这样会发生死锁吗?

我感觉同时提交的话 会
------其他解决方案--------------------
引用:
引用:
你的这些过程、游标都属于同一个事务,怎么可能发生死锁?除非他们中有自治事务

如果 存储在执行时,刚刚有他人也在同时对那些表进行操作,这样会发生死锁吗?


LZ应该去看看X.S锁协议,或者X、S加共享锁协议。只有在某人使用的了X锁(update、insert、delete等),才会锁住记录或者表,表现为事务记录。如果另外一个人要操作,与之冲突,数据库会让事务等待该锁释放后再执行,这并不会构成死锁。如果第一个获得X锁的人一直不释放,则另外一个试图获得X锁人就必须一直等待。

因此,假如前面的所说的两个人分别以两个程序表示,如果程序中在update/insert/delete之后执行了commit/rollback,则只有数据库出错的情况下才会出现死锁。对于Oracle而言,这种概率是非常低的。

如果不是程序对数据库进行操作,比如有人用toad进行了update、insert、delete操作,同时又没有commit/rollback,这时另一个人/程序对该表进行操作时,则很可能会碰到“死锁”状态。这里所谓的死锁其实是等待X锁资源释放。

如果只是读操作select,则不论多少人/程序同时操作,都不会产生死锁。

------其他解决方案--------------------
表现为事务锁
------其他解决方案--------------------
引用:
表现为事务锁

请问 我的存储是不是要加上 事务?
------其他解决方案--------------------
wqkjj
多谢你的建议,结贴。

我的异常网推荐解决方案:oracle存储过程,http://www.aiyiweb.com/oracle-develop/177537.html