代码逻辑死锁导致数据库超时
来源:互联网 发布:gom引擎插件源码 编辑:程序博客网 时间:2024/05/16 06:05
又是很久没记录工作点滴了,年后就忙着找新东家了,总算尘埃落定。不料,刚交接出去的系统就出问题了,系统老是超时。两天前看测试环境报错还没在意,因为什么代码也没改而且正式系统上也没问题,再加上公司权限系统切换有问题,大家什么异常第一个就想到权限系统。今天发现正式库上也报错了,一直报超时。于是查问题,最终结果是交接的人新加了个功能,代码中人为照成锁等待超时(在函数中前面加事务,后面没加事务,后面没加事务的等待锁释放,而事务等待执行完提交,于是造成等待超时)。
错误抽象出来如下:
- public static void Test()
- {
- using (SqlConnection myConnection = DBHelper.MyConnection)
- {
- myConnection.Open();
- SqlTransaction _varTrans = myConnection.BeginTransaction();
- try
- {
- InsertA(_varTrans);
- UpdateA(_varTrans);
- SelectA();
- _varTrans.Commit();
- }
- catch (Exception ex)
- {
- _varTrans.Rollback();
- Console.WriteLine(ex.ToString());
- }
- }
- }
查询方法:每次一卡,首先看所有的锁:exec sp_lock,查看ObjId不为0的,根据dbcc inputbuffer(spid)--spid为所有锁中的spid字段,看到执行的SQL语句为EventInfo字段,找到相应的代码。到代码中一找,原来刚接手项目的哥们新加了一个功能,断点调试,发现运行到后面的无事务查询卡住了,导致逻辑死锁,卡住的这段时间到数据库执行查询也是超时,遂以为这就是数据库的死锁。查看相关的资料发现,这种只是逻辑等待超时。
问题是解决了,然后就想可不可以用with(nolock)或者是with(readpast)的,经过业务考虑不适合;
进一步思考哪些情况会导致锁表等待,经过调查,个人从表象认为插入操作时锁主键索引,更新时锁定行,删除时锁主键索引。(具体测试代码见源码)
查询数据库锁表的语句如下:
- --查看所有锁表的语句
- use master;
- go
- if not exists(select * from sysobjects where name = '#LockDetails' and xtype='U')
- begin
- CREATE Table #LockDetails
- (
- [EventType] varchar(2000),
- [Parameters] int,
- EventInfo nvarchar(2000)
- );
- end
- go
- DECLARE crsr Cursor FOR
- SELECT spid blk FROM (
- select distinct resource_database_id dbid,
- resource_associated_entity_id objid,
- request_mode lockmode,
- request_session_id spid,
- b.name from master.sys.dm_tran_locks a
- left join master.sys.sysdatabases b on a.resource_database_id=b.dbid
- where resource_associated_entity_id<>0
- ) a;
- DECLARE @blk int;
- --游标开始
- open crsr;
- FETCH NEXT FROM crsr INTO @blk;
- WHILE (@@FETCH_STATUS=0)
- BEGIN;
- INSERT INTO #LockDetails exec('dbcc inputbuffer('+@blk+')')
- FETCH NEXT FROM crsr INTO @blk;
- END;
- close crsr;
- DEALLOCATE crsr;
- --游标结束
- select distinct * from #LockDetails;
- DROP Table #LockDetails;
源码下载
参考:
SQL Server死锁总结 :http://www.cnblogs.com/happyhippy/archive/2008/11/14/1333922.htmlmsdn的sp_lock :http://msdn.microsoft.com/zh-cn/library/ms187749.aspx
msdn的sys.dm_tran_locks :http://msdn.microsoft.com/zh-cn/library/ms190345.aspx
msdn的DBCC INPUTBUFFER:http://msdn.microsoft.com/zh-cn/library/ms187730(v=SQL.105).aspx
0 0
- 代码逻辑死锁导致数据库超时
- 代码逻辑死锁导致数据库超时
- 第三方扩展超时导致的php-cgi进程死锁
- java代码死锁导致事务无法提交
- JDBC连接超时,导致数据库操作失败
- 数据库死锁导致站点访问故障解决方案
- Mysql数据库更新操作导致死锁问题
- 在Java程序中处理数据库超时与死锁
- 在Java程序中处理数据库超时与死锁
- 数据库偶然出现死锁(等待锁超时)的情况处理:
- 在Java程序中处理数据库超时与死锁
- 数据库死锁导致分布事务中大批量更新数据库不成功
- 数据库日志文件自动增长导致连接超时的分析
- 数据库服务器磁盘空间爆满导致锁等待超时
- 应用重启会导致数据库锁记录,如何预防死锁
- 关于使用Spring导致c3p0数据库死锁问题
- 误用Connection.setAutoCommit导致的数据库死锁问题
- 转载: 关于使用Spring导致c3p0数据库死锁问题 zz
- Android(六) 常用控件(二)单选框,toast,checkbox,progressbar,listview
- 并发问题,锁,怎么处理死锁,脏数据处理
- 数据库锁等待超时 java.sql.SQLException: Lock wait timeout exceeded
- Linux RAID 磁盘矩阵
- ThinkPHP框架权限管理----权限分配的js实现
- 代码逻辑死锁导致数据库超时
- 什么时候应该使用索引,应该使用什么类型的索引
- 数组随机打乱洗牌排序
- 第十五周项目1 哈希表
- 记一次处理MySql锁等待(Lock wait timeout exceeded)
- 第十四周项目1-验证折半查找算法(1)
- 第十四周项目2 分块查找
- 处理mysql锁争用的一个示例
- 翻转单词顺序列