数据库update死锁

比较常见的死锁场景,并发批量update时的一个场景:

update cross_marketing
set gmtModified = NOW(),
pageview = pageview+ #extpageview#
WHERE marketingId=#marketingId#

第一次调用时,marketingId传入值顺序: 1,3,5,12

第二次调用时,marketingId传入值顺序:1,2,5,3

每次update时,会锁行。

那么第一次调用时,顺序锁行,当更新完3,准备跟新5的时候,发现5已经被第二次调用锁行了,就等待。而此时的第二次调用刚好跟新完5准备去拿3的锁,却发现被第一次调用占有,于是就出现死锁。

所以,我们要在批量更新,删除操作的时候,按照一个固定的顺序来排序,然后进行操作。

前面的例子,如果按照marketingId从小到大排序,就会变成:

第一次调用时,marketingId传入值顺序: 1,3,5,12

第二次调用时,marketingId传入值顺序:1,2,3,5

如此,就避免了死锁的发生。

时间: 2024-12-29 07:20:06

数据库update死锁的相关文章

数据库的死锁相关知识

死锁的定义 死锁是指两个或两个以上的进程在执行的过程中,由于竞态资源或由于彼此通信而造成的一种阻塞现象.若无外力作用,它们都将无法推进下去,此时称系统处于死锁状态,这些在互相等待的进程称为死锁进程. 数据库发生死锁的条件 1.资源不能共享.需要只能由一个进程或线程使用. 2.请求且保持.已经锁定的资源自己保持着不释放. 3.不剥夺. 自己申请的资源不能被别人剥夺. 4.循环等待. 想防止死锁只需将上述条件破坏: (1)尽量避免并发的执行涉及到修改数据的语句. (2)要求每个事务一次就将所有要用的

数据库update时切忌这样干

前言:数据库update时切忌这样干,这样干是什么?请随我来看看. 早些时候,客户发来这样一段文字"XX的,XXXXXXXX有个10万没到账,帮加上去."我马上动手查看数据库,寻找原因,随后回复了这样一句话"开玩笑吧".虽然之前发生过类似这样的问题,但都是小额资金,就手动在数据库里加了,遇到这么大的资金还是头一次,于是我加紧翻看数据库记录的节奏. 我发现用户的入金记录的确已经是审核通过状态,而用户的可用资金却没有加上,这已经让人意外了. 接着我查看代码,并没有发现逻

数据库一般死锁处理办法

1.先模拟一个死锁: 1 CREATE TABLE Lock1(C1 int default(0)); 2 CREATE TABLE Lock2(C1 int default(0)); 3 INSERT INTO Lock1 VALUES(1); 4 INSERT INTO Lock2 VALUES(1); 5 6 --将如下代码分别放到两个查询分析器窗口: 7 分析一窗口: 8 Begin Tran 9 Update Lock1 Set C1=C1+1; 10 WaitFor Delay '0

数据库中死锁那些事儿

转自:http://blog.csdn.net/eseaqyq/article/details/7795023 ———————————————————————————————————————————————————— 说起数据中的死锁,已经多次在笔试题目中遇到.今天特此做一个数据库死锁方面的总结,以绝后患,吼吼! 一.首先我们来看几个定义: 1.死锁 所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态

php当数据库update遇到并发,一个小坑

有一个答题的小项目,表的字段如下: id 用户id times 答题次数 questions 回答的问题id,这是一个php serialize()的字符串 当用户答完题像后端提交结果时,构建的post包如下: { 'id':1, 'questionid':38 } 后台逻辑如下: $user = User::findFirst("id = ?1",array('id'=>$_POST['id']));//取得用户模型 $questions = unserialize($user

SQLServer 2008数据库查看死锁、堵塞的SQL语句

死锁和堵塞一直是性能测试执行中关注的重点. 下面是我整理的监控sql server数据库,在性能测试过程中是否出现死锁.堵塞的SQL语句,还算比较准备,留下来备用. --每秒死锁数量 SELECT  * FROM    sys.dm_os_performance_counters  WHERE   counter_name LIKE 'Number of Deadlocksc%'; --查询当前阻塞 WITH CTE_SID ( BSID, SID, sql_handle ) AS ( SELE

发现操作系统的数据库出现死锁如何处理

where q.address = s.sql_addressand q.hash_value = s.sql_hash_valueand s.paddr = p.addrand exists (select sidfrom v$lockwhere block=1 and sid=s.sid):如果提示no rows select(没有行选中) ,则表示没有业务方面的锁,现在的锁不影响业务系统的正常运行,如果有这些提示,表示已经有锁已经影响业务系统的正常运行,根据下一步操作查询导致死锁语句,告之

数据库update的异常一例

调查一列bug,偶然发现了update的一个特性:update t set a=a+1 where id=4; 这样一条简单的语句,也会发生让人意外的事情: 如果 a 的初始值为null时,无论你update多少次,a 的值始终是 null  !!!!!! 直接上图: 测试了一下 mysql, sql server 2008都是一样的,处理方法类似,mysql 有 ifnull(a,0) ,sql server 中有 isnull(a,0) 方法: update model_model set

mysql数据库update时只更新部分数据方法

需求:更新url中最一个字符的'-1'改为'-5',前面的内容保持不变 url列的内容如下:http://h5game.ecs.cedarmg.com/a/captal/dispther.do?deviceid=b-01-1 SELECT * from qrmsg WHERE url LIKE '%1' http://h5game.ecs.cedarmg.com/c/captal/dispther.do?deviceid=b-01-1 需要把最后这个-1改成-5 操作方式如下: UPDATE q