Transaction中SQL的顺序引起的死锁

标签: transaction sql 死锁 | 发表时间:2013-10-17 20:49 | 作者:DLevin
出处:http://www.blogjava.net/
因为项目的数据更新频率很高,导致经常出现死锁的问题。感觉以下遇到的一种情况比较典型,也比较tricky,计之。

问题描述:
如以下两条非常简单的SQL语句,它们共同组成了一个Transaction,那么在多线程高频率执行时就会引起死锁问题(当然这里要考虑锁的级别问题,一般多类似这种系统都会选择行锁,那么以下引起死锁的条件是两条语句都对同一行操作):
select <column1> from <table> where <column2> = ? 
update <table> set <column1> = %d where <column2> = '%s'

问题分析:
select语句需要“Shared Lock”,因而多个线程可以同时进入,而update需要“Exclusive Lock”,当两个线程同时执行了select语句,而获得了“Shared Lock”,而他们在接下来执行update语句时,都需要获得“Exclusive Lock”而产生竞争,导致死锁。

解决方案1:
互换他们的顺序,这样,在第一次执行update语句时,他们会竞争"Exclusive Lock"而引起没有得到“Exclusive Lock”的线程等待:
1, update <table> set <column2> = <column2> + <some value> where <column1> = '%s' 
2. select <column1> from <table> where <column2> = ? 
3. <column1> - <some value> to get the old <column1> value.

解决方案2:
采用“Hold Lock”方式,即在所有操作之前做一个dummy的update操作,这样可以保证在进Transaction之前需要先获得一个“Exclusive Lock”

 



DLevin 2013-10-17 20:49 发表评论

相关 [transaction sql 死锁] 推荐:

Transaction中SQL的顺序引起的死锁

- - BlogJava-首页技术区
因为项目的数据更新频率很高,导致经常出现死锁的问题. 感觉以下遇到的一种情况比较典型,也比较tricky,计之. 如以下两条非常简单的SQL语句,它们共同组成了一个Transaction,那么在多线程高频率执行时就会引起死锁问题(当然这里要考虑锁的级别问题,一般多类似这种系统都会选择行锁,那么以下引起死锁的条件是两条语句都对同一行操作): select  from  where  = ? .

SQL Server 中的事务和锁(三)-Range S-U,X-X 以及死锁

- Bloger - 博客园-首页原创精华区
Range T-K 到底代表了什么. Range T-K Lock 代表了在 SERIALIZABLE 隔离级别中,为了保护范围内的数据不被并发的事务影响而使用的一类锁模式(避免幻读). 第一个部分代表了他锁定了一个索引范围,在这个范围内,所有索引使用 T 锁进行锁定;. 第二个部分是而这个范围内已经命中的Key,这些 Key 将使用 K 锁进行锁定.

Sql Server 高频,高并发访问中的键查找死锁解析 - shanks_gao

- - 博客园_首页
死锁对于DBA或是数据库开发人员而言并不陌生,它的引发多种多样,一般而言,数据库应用的开发者在设计时都会有一定的考量进而尽量避免死锁的产生.但有时因为一些特殊应用场景如高频查询,高并发查询下由于数据库设计的潜在问题,一些不易捕捉的死锁可能出现从而影响业务.这里为大家介绍由于设计问题引起的键查找死锁及相关的解决办法..

spring @Transaction事务不生效问题

- - Java - 编程语言 - ITeye博客
如果你已经排除了以下问题:. 或是数据库本身不支持, 如MySQL的Myisam. 不防看看是不是由多数据源引起的:. 多数据源我们一般这样配置:. 这样, 其中一个数据源就是默认的数据源, 如A. 如果使用@Transaction注解开启事务, 默认使用默认数据源A来进行开启, 提交, 回滚 事务, 这个时候如果@Transaction方法里面是对com.B.dao进行的操作, 那么其实事务也是作用在A数据源上, 就会产生事务不生效的假象.

MySQL 事务RUNNING状态引发的Transaction timed out: deadline问题

- - CSDN博客推荐文章
    朋友说简单的查询导致Transaction timed out: deadline问题,怀疑是数据库表锁了,. 1,应用故障描述Deadline问题: . 2,检查Innodb存储引擎状态以及表锁状态.         SHOW ENINGE INNODB STATUS;没有死锁信息以及其它异常信息;去查询系统表INNODB_LOCKS、INNODB_LOCK_WAITS表都为NULL,只有INNODB_TRX表有记录,并且处于长时间RUNNING状态,判断是因为事务没有提交或者回滚的缘故.

MySQL数据库事务隔离级别(Transaction Isolation Level)

- - RSS - IT博客云
修改事务隔离级别的方法:. 1.全局修改,修改 mysql.ini配置文件,在最后加上. 1 #可选参数有: READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE. 这里全局默认是 REPEATABLE-READ,其实MySQL本来默认也是这个级别.

分布式事务中间件 TCC-Transaction 源码分析 —— 项目实战

- - IT瘾-geek
摘要: 原创出处 http://www.iocoder.cn/TCC-Transaction/http-sample/「芋道源码」欢迎转载,保留摘要,谢谢. 本文主要基于 TCC-Transaction 1.2.3.3 正式版. 4.2 Confirm / Cancel 阶段. 微信公众号:【芋道源码】有福利:.

RabbitMQ的transaction、confirm、ack三个概念的解释 - brady-wang - 博客园

- -
在使用RabbitMQ的过程中,肯定会遇到这样的几个概念:transaction、confirm、ack. 本文介绍一下这几个概念,以及他们之间的关系. RabbitMQ是采用的AMQP协议,AMQP协议定义了”确认”(acknowledgement),它是从consumer到RabbitMQ的确认,表示一条消息已经被客户端正确处理.

PL/SQL动态SQL(原创)

- - ITeye博客
使用动态SQL是在编写PL/SQL过程时经常使用的方法之一. 很多情况下,比如根据业务的需要,如果输入不同查询条件,则生成不同的执行SQL查询语句,对于这种情况需要使用动态SQL来完成. 再比如,对于分页的情况,对于不同的表,必定存在不同的字段,因此使用静态SQL则只能针对某几个特定的表来形成分页.

Derby SQL 分页

- - ITeye博客
    之前在网上看到有人问 Derby SQL 分页实现的问题,网上有人给出这样的解决方案,SQL 如下:. 其实,这样的分页查询,性能不理想,我试过在 300W 数据量中采用这种分页方式,需要 20~30秒之久;其实 Derby 10.6 以上版本有更好的分页支持,直接给出 SQL 实现如下:.