Transaction中SQL的顺序引起的死锁

简介:
因为项目的数据更新频率很高,导致经常出现死锁的问题。感觉以下遇到的一种情况比较典型,也比较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”

相关文章
|
SQL 存储
在 SQL Server 中查找活动连接和死锁
在SQL Server中有几种方法可以找到活动的 SQL 连接。让我们看看一些使用 T-SQL 查询的简单快捷的方法。
346 0
|
SQL 存储 Java
mybatis如何直接 执行传入的任意sql语句 并按照顺序取出查询的结果集
mybatis如何直接 执行传入的任意sql语句 并按照顺序取出查询的结果集 需求: 1.直接执行前端传来的任何sql语句,parameterType="String", 2.对于任何sql语句,其返回值类型无法用resultMap在xml文件里配置或者返回具体的bean类型,因此设置resultType="java.util.Map",但是Map并不保证存入取出顺序一致, 因此设置resultType="java.util.LinkedHashMap",为保证查询的字段值有序(存入与取出顺序一致)所以采用LinkedHashMap。
2452 0
|
SQL 关系型数据库 MySQL
软件测试mysql面试题: SQL SELECT的顺序是什么?
软件测试mysql面试题: SQL SELECT的顺序是什么?
100 0
SQL查询语句的书写顺序和执行顺序
SQL查询语句的书写顺序和执行顺序
SQL查询语句的书写顺序和执行顺序
|
SQL 数据库
31 张图 | 一文搞懂 SQL事务+隔离级别+阻塞+死锁
31 张图 | 一文搞懂 SQL事务+隔离级别+阻塞+死锁
255 0
31 张图 | 一文搞懂 SQL事务+隔离级别+阻塞+死锁
|
SQL 关系型数据库 MySQL
【sql语句基础】——查(select)(单表查询顺序补充)
【sql语句基础】——查(select)(单表查询顺序补充)
|
SQL Oracle NoSQL
JDK的sql设计不合理导致的驱动类初始化死锁问题
JDK的sql设计不合理导致的驱动类初始化死锁问题
JDK的sql设计不合理导致的驱动类初始化死锁问题
|
SQL 存储 数据库
处理令人心烦的数据库事务日志 (SQL Server Transaction Log Files)
经常, 我们会被过快增长的数据库事务日志Transaction Log而困扰, 如果我们没有正确及时的处理, 可能会造成数据库交易无法进行, 服务器磁盘空间占光等问题. 在SQL Server的使用过程中, 我经常帮助用户和数据库的维护人员处理日志Transaction Log太大后造成的系统瘫痪的问题. 其实这个问题很容易避免. 今天我给大家分享下, 是什么造成了日志增长过大的问题. 和如何避免这种问题再次发生. 该文章的语句适用于SQL Server 2015 及其以后的版本 每一个数据库至少有两个文件: 一个是数据文件(Data file), 一个是事务日志文件(Transaction
785 0
|
SQL 存储 消息中间件
一个线上SQL死锁异常分析:深入了解事务和锁
引发死锁的原因是什么?如何避免?本文详细介绍了和死锁有关的知识点,通过深入分析MySQL事务和锁的机制,结合案例背景,找到了问题的所在,并梳理了解决方案,详解其原理。希望对同学们有所启发。
一个线上SQL死锁异常分析:深入了解事务和锁
|
SQL 测试技术 C#
SQL Server死锁中的会话隔离级别为序列化(Serializable)实验测试
SQL Server死锁中的会话隔离级别为序列化(Serializable)实验测试最近在分析SQL Server的死锁时,发现一个比较有意思的现象,发现死锁当中一个会话的隔离级别为序列化(Serializable),这个是让人比较奇怪的地方,我们知道SQL Server数据库的默认隔离级别为已提交读(READ COMMITTED),除非人为设置事务隔离级别(TRANSACTION ISOLATION LEVEL),否则事务隔离级别会使用数据库的默认隔离级别。
21778 0
下一篇
无影云桌面