当运行执行INSERT和UPDATE的存储过程(来自.NET应用程序)时,我有时(但不经常,真的)并随机获取此错误:
错误[40001] [DataDirect] [ODBC Sybase Wire协议驱动程序] [SQL Server]您的服务器命令(系列ID#0,进程ID#46)遇到死锁情况.请重新运行您的命令.
我怎样才能解决这个问题?
谢谢.
我有一个Oracle数据库软件包,它经常导致我认为是ITL(感兴趣的事务列表)的死锁.跟踪文件的相关部分如下所示.
Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TM-0000cb52-00000000 22 131 S 23 143 SS
TM-0000ceec-00000000 23 143 SX 32 138 SX SSX
TM-0000cb52-00000000 30 138 SX 22 131 S
session 131: DID 0001-0016-00000D1C session 143: DID 0001-0017-000055D5
session 143: DID 0001-0017-000055D5 session 138: DID 0001-001E-000067A0
session 138: DID 0001-001E-000067A0 session 131: DID 0001-0016-00000D1C
Rows waited on:
Session 143: no row
Session 138: no row
Session 131: no row
Run Code Online (Sandbox Code Playgroud)
此表上没有位图索引,因此不是原因.据我所知,缺少"行等待"加上Waiter等待列中的"S"可能表明这是ITL的死锁.此外,该表经常被写入(大约8次插入或同时更新,通常每分钟240次),因此ITL死锁似乎很有可能.
我增加了表的INITRANS参数,它的索引为100,并将表上的PCT_FREE从10增加到20(然后重建了索引),但死锁仍在发生.在更新期间,僵局似乎最常发生,但这可能只是巧合,因为我只追踪了几次.
我的问题有两方面:
1)这实际上是ITL的僵局吗? …
我在我的大型Web应用程序中收到了很多死锁.
如何自动重新运行死锁事务?(ASP.NET MVC/SQL Server)
在这里,我想重新运行死锁事务,但我被告知摆脱死锁 - 它比试图赶上死锁要好得多.
所以我花了整整一天的时间用SQL Profiler,设置跟踪键等等.这就是我得到的.
有一张Users桌子.我有一个非常高的可用页面与以下查询(它不是唯一的查询,但它是导致麻烦的那个)
UPDATE Users
SET views = views + 1
WHERE ID IN (SELECT AuthorID FROM Articles WHERE ArticleID = @ArticleID)
Run Code Online (Sandbox Code Playgroud)
然后在所有页面中都有以下查询:
User = DB.Users.SingleOrDefault(u => u.Password == password && u.Name == username);
Run Code Online (Sandbox Code Playgroud)
这就是我从cookie中获取用户的地方.
通常会发生死锁,并且第二个Linq-to-SQL查询被选为受害者,因此它不会运行,并且我的站点用户会看到错误屏幕.
这是来自SQL事件探查器捕获的.XDL图形的信息(它只是第一个死锁,它不是唯一的.整个列表都是巨大的.):
<deadlock-list>
<deadlock victim="process824df048">
<process-list>
<process id="process824df048" taskpriority="0" logused="0" waitresource="PAGE: 7:1:13921" waittime="1830" ownerId="91418" transactionname="SELECT" lasttranstarted="2010-05-31T12:17:37.663" XDES="0x868175e0" lockMode="S" schedulerid="2" kpid="5076" status="suspended" spid="72" sbid="0" ecid="2" priority="0" trancount="0" lastbatchstarted="2010-05-31T12:17:37.663" lastbatchcompleted="2010-05-31T12:17:37.663" clientapp=".Net SqlClient Data Provider" hostname="WIN-S41KV2CLS67" hostpid="6920" …Run Code Online (Sandbox Code Playgroud) 我们的应用程序(使用NHibernate和ASP.NET MVC)在进行压力测试时会抛出大量的NHibernate事务错误.主要类型是:
有人可以帮助我找出异常1的原因吗?我知道我必须处理代码中的其他异常.有人能指出我可以帮助我以有效的方式处理这些错误的资源吗?
问:我们如何管理会话和交易?
答:我们正在使用Autofac.对于每个服务器请求,我们创建一个新的请求容器,其中包含容器生命周期范围内的会话.在激活会话时,我们开始交易.请求完成后,我们提交事务.在某些情况下,交易可能很大.为简化起见,每个服务器请求都包含在事务中.
有人可以帮我阅读/理解这个死锁图吗?
我不明白为什么进程75要求锁定他已经锁定的对象?

在我到目前为止看到的所有SQL死锁示例中,执行SELECT/ UPDATE等时出现死锁.
如果我的所有陈述都成功执行,那么当我出现死锁时是否有可能出现COMMIT?
我正试图用我的ORM捕获死锁异常,并想知道使用try{}周围flush()是否足够,或者它是否应该包装commit().
Database: MSSQL server 2012;
Isolation level: READ_COMMITTED_SNAPSHOT
Now I have a table "COV_HOLES_PERIODDATE". It has a composite primary key which is also a clustered index. No other indexes on this table.
There are many threads(via Java) working concurrently. Each thread will first do a "select for update" on a DIFFERENT primary key via lock hint (updlock, rowlock), then do some work, then update table for this row. It is guaranteed from Java side that each thread is operating on a …
我运行多台服务器,每台服务器都在运行多更新语句,例如这些
UPDATE user SET ... WHERE user_id = 2;
UPDATE user SET ... WHERE user_id = 1;
UPDATE user SET ... WHERE user_id = 3;
Run Code Online (Sandbox Code Playgroud)
如果有并发更新,例如:
UPDATE user SET ... WHERE user_id = 1;
UPDATE user SET ... WHERE user_id = 2;
Run Code Online (Sandbox Code Playgroud)
然后我会遇到错误 deadlock detected
现在,我的解决方法是在客户端对更新语句进行排序,并始终保证 id 的顺序相同。即我总是在客户端对语句进行排序ASC by user_id
到目前为止,这似乎解决了这个问题,但我仍然有疑问:
我想收集有关 PostgreSQL 死锁中“获胜者”事务和“失败者”事务的事后调试信息。
LOG: process 11367 still waiting for ShareLock on transaction 717 after 1000.108 ms
DETAIL: Process holding the lock: 11366. Wait queue: 11367.
CONTEXT: while updating tuple (0,2) in relation "foo"
STATEMENT: UPDATE foo SET value = 3;
我可以使用更好的数据源来收集这些信息吗?
我遇到了僵局,并试图找出其背后的原因。
问题可以简化为:
表:
create table testdl (id int auto_increment, c int, primary key (id), key idx_c (c));
隔离级别可重复读取
(Tx1): begin; delete from testdl where c = 1000; -- nothing is deleted coz the table is empty
(Tx2): begin; insert into testdl (c) values (?);
无论Tx2中的值是多少,它都会挂起。因此,从根本上说,当delete from testdl where c = 1000找不到匹配项时,Tx1保持整个范围的间隙(-∞,+∞),对吗?
所以我的问题是:这是设计使然吗?这是什么意思呢?
更新:
假设我们已经有以下记录testdl:
+----+------+
| id | c |
+----+------+
| 1 | 1000 |
+----+------+
Run Code Online (Sandbox Code Playgroud)
情况1:
(Tx1): select * from testdl where c = …
deadlock ×4
sql ×3
mysql ×2
postgresql ×2
sql-server ×2
asp.net-mvc ×1
concurrency ×1
database ×1
nhibernate ×1
oracle ×1
oracle10g ×1
sybase-ase ×1
transactions ×1