2016-07-28 2 views
0

Запуск стандарта Microsoft SQL 2012, без сжатия, без разделов. Работает на Windows Server 2008 R2. Моя программа-загрузчик - VS C# 2013, чистый 64-разрядный, .NET 4.5.2 Я использую Dapper 1.42 для своего ORM. Я НЕ использую commit/rollback/transaction logic, это просто простые вставки.C# Dapper загрузчик в MS-SQL 2012 deadlocks на вставке

В верхней части загрузчика я выдаю «УСТАНОВИТЬ ВОССТАНОВЛЕНИЕ ПРОСТОТА» (это было сделано, чтобы попытаться решить эту проблему).

Загрузчик читает .csv, выполняет некоторую обработку данных, а затем делает вставку, на самом деле простейшую форму программы, это всего лишь несколько строк кода. Загрузчик никогда не выбирает. Загрузчик - это единственный процесс, выполняющийся на этом сервере (тестовый сервер). Погрузчик не имеет многопоточной резьбы. Я вставляю commandtimeout = 0.

Я постоянно продолжаю получать транзакцию (идентификатор процесса xx) зашел в тупик на ресурсах блокировки другим процессом и был выбран в качестве жертвы взаимоблокировки. Перезапустите транзакцию ».

Ошибка звучит очевидно, она говорит, что у меня есть 2 процесса, и один из них является взаимоблокировкой. Но я на тестовом сервере, я единственный пользователь, другого процесса не существует.

Я в недоумении отлаживать это. В моем заявлении «catch» я выдаю эту команду SQL, чтобы поймать, что еще работает, но показывает, что NOTHING работает каждый раз, когда я получаю ошибку. Итак, если ничего не работает, почему я продолжаю получать помехи на вставке?

SELECT L.request_session_id AS SPID, DB_NAME(L.resource_database_id) AS DatabaseName, O.Name AS LockedObjectName, P.object_id AS LockedObjectId, L.resource_type AS LockedResource, L.request_mode AS LockType, ST.text AS SqlStatementText, ES.login_name AS LoginName, ES.host_name AS HostName, TST.is_user_transaction as IsUserTransaction, AT.name as TransactionName, CN.auth_scheme as AuthenticationMethod 
FROM sys.dm_tran_locks L 
LEFT JOIN sys.partitions P ON P.hobt_id = L.resource_associated_entity_id 
LEFT JOIN sys.objects O ON O.object_id = P.object_id 
LEFT JOIN sys.dm_exec_sessions ES ON ES.session_id = L.request_session_id 
LEFT JOIN sys.dm_tran_session_transactions TST ON ES.session_id = TST.session_id 
LEFT JOIN sys.dm_tran_active_transactions AT ON TST.transaction_id = AT.transaction_id 
LEFT JOIN sys.dm_exec_connections CN ON CN.session_id = ES.session_id 
CROSS APPLY sys.dm_exec_sql_text(CN.most_recent_sql_handle) AS ST 
WHERE DB_NAME(L.resource_database_id) = DB_NAME() 

ответ

0

В моем заявлении «поймать», я выполняю эту команду SQL, чтобы поймать, что еще работает

Когда тупиковый происходит сделка жертва откатывается. Это освобождает все блокировки и, таким образом, позволяет конкурирующим сделкам (транзакциям) продолжать. Только после завершение отката - это контроль, возвращенный жертве сеанс и исключение. К тому моменту, когда ваши catch запускают параллельные процессы, вероятно, завершены.

То, что вы пытаетесь сделать, в корне неверно. Не говоря уже, вы уже есть средства для сбора информации о тупиковой:

И, как последний вопрос: sys.dm_exec_sessions permissions :

Если у пользователя есть разрешение VIEW SERVER STATE на сервере, пользователь увидит все исполняемые сессии в экземпляре SQL Server; в противном случае пользователь увидит только текущий сеанс.

Смежные вопросы