我们在使用 EF 并行插入多个实体时遇到问题。WCF 操作由许多进程调用,以在每次调用中生成具有不同分布式事务的实体。正如我们在 sql server profiler 中看到的,它生成以下 sql:
(@0 int,@1 nvarchar(32),@2 datetime2(7),@3 nvarchar(64),@4 int,@5 int,@6 bit)
insert [dbo].[CommandRequests](
[CommandId]
, [DeviceId]
, [StartDateTime]
, [EndDateTime]
, [Parameters]
, [Caller]
, [Result]
, [Priority]
, [Timeout]
, [ParentRequestId]
, [IsSuccessful]
, [Host])
values (@0, @1, @2, null, null, @3, null, @4, @5, null, @6, null)
select [CommandRequestId]
from [dbo].[CommandRequests]
where @@ROWCOUNT > 0 and [CommandRequestId] = scope_identity()
Run Code Online (Sandbox Code Playgroud)
所以 EF 给我们一个插入,然后是一个选择。因为它是并行完成的,所以很多都因死锁而中止。
我们使用的是 EF 4.0,而不是 4.1 或 4.2。
知道如何解决这个问题吗?我见过这个,但它很旧: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/4f634d8f-1281-430b-b664-ec7ca413b387/
我刚刚了解到,当我在 neo4j 中创建两个节点之间的关系时,它们都被锁定(http://docs.neo4j.org/chunked/stable/transactions-locking.html)。然而,在我们的项目中,我们有可以实例化的元素,并且最终在图中有两个通过“INSTANCE_OF”关系链接的节点。例如,如果我实例化元素 B,我就会有一个新元素 B1。它们存储在图中,如 B<-INSTANCE_OF-B1。我的问题是许多用户可以同时实例化元素 B,这会导致死锁。请问我怎样才能避免这些僵局?我不需要在 B 上写入属性,我只想将 B1 “附加”到我的图中的 B 。在 B1 中拥有代表 B id 的属性是否会比将它们与关系链接起来是更好的解决方案?我认为不会,因为我们失去了所有的图形兴趣,但我真的不知道如何避免这些僵局?
非常感谢您的帮助
我有一种情况,当使用多个线程时,将新记录从 C# ASP.NET Web API 插入 SQL Server 数据库表会导致死锁。这是由初始SELECT获取共享范围锁 (RangeS-S) 引起的,然后在INSERT发生时将其转换为 RangeI-N。
缩写和匿名死锁 XML 如下所示。
<deadlock-list>
<deadlock victim="process19d91c28">
<process-list>
<process id="process19d91c28" taskpriority="0" logused="372" waitresource="KEY: 6:72057594044416000 (ffffffffffff)" waittime="3914" ownerId="1072531" transactionname="user_transaction" lasttranstarted="2015-03-27T15:41:26.670" XDES="0x5faad0d0" lockMode="RangeI-N" schedulerid="3" kpid="4300" status="suspended" spid="58" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2015-03-27T15:41:26.693" lastbatchcompleted="2015-03-27T15:41:26.693" lastattention="1900-01-01T00:00:00.693" clientapp=".Net SqlClient Data Provider" hostname="MYHOST" hostpid="17300" loginname="MYDOMAIN\XYZ_DB_DEV" isolationlevel="serializable (4)" xactid="1072531" currentdb="6" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="XYZ_Local.dbo.Article_Insert" line="20" stmtstart="1100" stmtend="2372" sqlhandle="0x0300060049c6306a7d37c200b0a3000001000000000000000000000000000000000000000000000000000000">
INSERT INTO Article (
-- ABREVIATED
) VALUES (
-- ABREVIATED
</frame> …Run Code Online (Sandbox Code Playgroud) 我对 sqlalchemy-psql 中的锁定机制如何工作感到非常困惑。我正在使用 sqlalchemy 和 postgres 运行 python-flask 应用程序。由于我有多个线程处理一些数据并在 psql 上更新它,所以我遇到了以下死锁:
2015-12-31 17:[错误](由于查询调用的自动刷新而引发;如果此刷新过早发生,请考虑使用 session.no_autoflush 块)(psycopg2.extensions.TransactionRollbackError)检测到死锁
详细信息:进程 22833 等待事务 14114188 上的 ShareLock;被进程 19759 阻止。
进程19759等待事务14114189上的ShareLock;被进程 22833 阻止。
这是否会导致僵局:
Thread 1 Thread 2
| (start an sqlalchemy session) |
db.session() db.session()
|(Using sqlalchemy) |
Update row1 of table1 Update row2 of table 1
| |
Update row2 of table1 Update row1 of table1
| |
session.commit() session.commit()
Run Code Online (Sandbox Code Playgroud)
以下是我的问题的一些答案,但我无法将它们与 sqlalchemy 联系起来。
python postgresql sqlalchemy database-deadlocks flask-sqlalchemy
例子:
START TRANSACTION;
UPDATE books SET printedCount=1000 WHERE id=5;
Run Code Online (Sandbox Code Playgroud)
如何找到表的哪些行books被打开的事务(或这些行的 id、主键)锁定?我想跟踪此信息以防止高负载 Web 应用程序中出现死锁,如果可能受这些查询影响的行已被锁定,则可能会延迟某些更新查询。
我无法解释 MySql(5.7,InnoDB)的死锁输出。我知道死锁最终会通过更改应用程序级别代码来解决,并且您无法从这段代码中找到根本原因。然而,希望有人能够告诉我为什么我对这个 MySql 诊断的解释是不正确的。
------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-04-09 19:41:39 0x2b7323ef1700
*** (1) TRANSACTION:
TRANSACTION 33312589, ACTIVE 16 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 150744, OS thread handle 47781157312256, query id 53141856 ec2-34-250-106-67.eu-west-1.compute.amazonaws.com 34.250.106.67 sc_appuser3 statistics
/* requestId: 11e8-3c2d-fb145a10-b404-0242ac110003 */ SELECT locator FROM policy WHERE locator = 'df0d7ef5-2e14-4664-90b2-2bfb3f35cce2' AND tenant_locator = '8df5d824-6de9-4e21-8135-b19303aec800' FOR UPDATE
*** (1) WAITING FOR THIS LOCK …Run Code Online (Sandbox Code Playgroud) 我很好奇为什么当主键不存在时,两个使用主键的并发语句会导致 MySQL 死锁DELETE。INSERT该示例旨在以最简单的形式说明该问题。
这是设置。
> SELECT @@GLOBAL.tx_isolation, @@tx_isolation;
+-------------------------+------------------+
| @@GLOBAL.tx_isolation | @@tx_isolation |
|-------------------------+------------------|
| REPEATABLE-READ | REPEATABLE-READ |
+-------------------------+------------------+
1 row in set
Time: 0.002s
> select version();
+-------------+
| version() |
|-------------|
| 5.7.12 |
+-------------+
1 row in set
Time: 0.002s
create table lock_test ( id int(11) not null, primary key (`id`) );
Run Code Online (Sandbox Code Playgroud)
下面,1>代表一个mysql终端,2>代表另一个终端。
1> begin;
1> delete from lock_test where id = 1;
2> begin; …Run Code Online (Sandbox Code Playgroud) 我在我的应用程序中看到持续的死锁,即使它不执行 select 语句、delete 语句和 update 语句。它只是插入全新的数据。
TL;DR:这似乎与外键有关。如果我删除它,那么我根本不会遇到任何死锁。但由于显而易见的原因,这不是一个可接受的解决方案。
鉴于下表结构
CREATE TABLE [dbo].[IncomingFile]
(
[Id] UNIQUEIDENTIFIER NOT NULL,
[ConcurrencyVersion] RowVersion NOT NULL,
CONSTRAINT [PK_IncomingFile] PRIMARY KEY CLUSTERED([Id])
)
GO
CREATE TABLE [dbo].[IncomingFileEvent]
(
[Id] UNIQUEIDENTIFIER NOT NULL,
[ConcurrencyVersion] RowVersion NOT NULL,
[IncomingFileId] UNIQUEIDENTIFIER NOT NULL,
CONSTRAINT [PK_IncomingFileEvent] PRIMARY KEY CLUSTERED([Id]),
CONSTRAINT [FK_IncomingFileEvent_IncomingFileId]
FOREIGN KEY ([IncomingFileId])
REFERENCES [dbo].[IncomingFile] ([Id])
)
GO
Run Code Online (Sandbox Code Playgroud)
当我遇到多个并发任务插入数据时,我总是看到一个死锁。READ_COMMITTED_SNAPSHOT在我的数据库选项中启用(即使我没有阅读)。
这是将重现该问题的代码。如果您没有遇到问题,请增加NumberOfTasksPerCpu程序顶部的常量。
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace …Run Code Online (Sandbox Code Playgroud) 我们在开发过程中遇到了一个奇怪的问题,正在寻找有关SELECT INTO临时表上的自死锁问题的解释。
我们有一个例程将一些相当复杂的 JSON 文档转换为表格形式。我们目前正在使用 来完成此任务OPENJSON,通常效果很好。
这种转变是在触发器的背景下发生的。当向表中插入一行或多行时,会生成一组 JSON 文档,将其存储在单个变量中,并传递到以下例程中。它看起来像这样:
SELECT
a.[ID],
b.[Some stuff here...]
INTO #MyTempTable
FROM OPENJSON(@MyJSONDocuments)
WITH (
ID VARCHAR(40),
nestedDocument NVARCHAR(MAX) AS JSON) a
CROSS APPLY OPENJSON(nestedDocument ,'$') b
Run Code Online (Sandbox Code Playgroud)
当我们在 SSMS 中运行它时,它工作得很好。临时表已生成并填充,没有问题。当我们将其移至触发器并仅将一行插入基础表(即@MyJSONDocuments单个文档的数组)时,它也可以正常工作。当我们插入两行或更多行,并且@MyJSONDocuments数组中包含多个文档时,我们会遇到可怕的情况:
Transaction (Process ID x) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Run Code Online (Sandbox Code Playgroud)
当我们将SELECT INTO语句包装在 SSMS 中的 aBEGIN TRAN / COMMIT …
sql-server json temp-tables sqlperformance database-deadlocks
我有一个针对 SQL Server 2016 数据库运行的应用程序,该数据库导致死锁。
死锁图显示了底层对象的 Objectid 和对象名称。它还提供了截断的 SQL 语句。
但是,某些语句相当大,超出了实体的 XML 死锁报告中的 1024 个字符限制<inputbuf>。我希望能够查看这些锁中涉及的完整语句,以便我可以重现和调试问题。
有没有一种方法可以增加这个限制,或者有没有一种方法可以在给定死锁图中包含的事务描述符的情况下找到完整的 SQL 语句?
sql-server ×4
mysql ×3
deadlock ×2
innodb ×2
c# ×1
json ×1
mariadb ×1
neo4j ×1
postgresql ×1
python ×1
sqlalchemy ×1
temp-tables ×1
transactions ×1