2010-07-26 3 views
2

Я попытался сохранить граф объектов с помощью NHibernate. Сохранение завершилось неудачей из-за нарушения невязкого ограничения.SQL Server - таблица, кажется, заблокирована

Теперь я обнаружил, что таблица в базе данных, соответствующая одному из объектов на графике, теперь заблокирована. Я не могу запросить его. Всякий раз, когда я пытаюсь, он просто сидит там, ничего не делая, пока я не отменим запрос. Это происходит примерно полчаса.

В коде сохранения транзакция сначала фиксируется, а затем удаляется.

SELECT @@ TRANCOUNT против базы данных дает 0.

Есть а) Что происходит на идеи и б) Как я могу получить таблицу обратно?

ответ

3

@@TRANCOUNT относится к current connection.

Предполагая, что у вас есть достаточные разрешения на сервере.

select hostname,program_name, spid,text from master.sys.sysprocesses 
outer apply sys.dm_exec_sql_text(sql_handle) s 
WHERE open_tran>0 

содержит любые соединения с транзакциями, открытыми в настоящее время, вместе с последним текстом, выполненным этим соединением. Я использую sysprocesses по причинам here.

Если приведенный выше запрос показывает ваш виновник, то вы можете получить SPID и использовать kill <spidnumber> бесцеремонно раскатать back.You, возможно, захотите рассмотреть вопрос об установлении XACT_ABORT на будущие запросы поэтому ошибки не будут оставлять сделки открытыми.

+0

Неверное имя объекта 'sysprocesses'. В какой схеме это? – David

+0

Для SQL2005 + он находится в схеме 'sys', но' sys' является необязательным для обратной совместимости, поэтому похоже, что у вас нет разрешений для его просмотра. Можете ли вы сделать что-то на стороне своего приложения, чтобы закрыть соединение? Также у вас есть аналогичная проблема с предложениями @ DOK? –

+0

Если я не могу просмотреть его, никто не сможет! Это моя база данных ... Предложения DOK прошли нормально. – David

0

Если у вас есть доступ к базе данных, попробуйте запустить sp_lock, чтобы узнать, у кого заблокирована таблица.

Редактировать: Это будет возвращать записи с несколькими столбцами информации, описанной here. Одна из этих колонок - spid. Вы можете использовать sp_who (или sp_who2), чтобы узнать, кто вошел в систему, и найдите spid с замком.

Если у вас есть разрешение на просмотр состояния сервера, вы также можете использовать sys.dm_tran_locks.

+0

sp_lock сообщает мне, что у меня есть два замка KEY, блокировка PAG и блокировка TAB. Как узнать, кто такой пользователь? И как удалить блокировки? – David

0

Вы уверены, что правильно выбрали свою сессию? Это, как правило, причиной таких проблем ...

0

попробуйте запустить это:

SELECT 
    r.session_id AS spid 
     ,r.cpu_time,r.reads,r.writes,r.logical_reads 
     ,r.blocking_session_id AS BlockingSPID 
     ,LEFT(OBJECT_NAME(st.objectid, st.dbid),50) AS ShortObjectName 
     ,LEFT(DB_NAME(r.database_id),50) AS DatabaseName 
     ,s.program_name 
     ,s.login_name 
     ,OBJECT_NAME(st.objectid, st.dbid) AS ObjectName 
     ,SUBSTRING(st.text, (r.statement_start_offset/2)+1,((CASE r.statement_end_offset 
                    WHEN -1 THEN DATALENGTH(st.text) 
                    ELSE r.statement_end_offset 
                   END - r.statement_start_offset 
                  )/2 
                  ) + 1 
       ) AS SQLText 
    FROM sys.dm_exec_requests       r 
     JOIN sys.dm_exec_sessions      s ON r.session_id = s.session_id 
     CROSS APPLY sys.dm_exec_sql_text (sql_handle) st 
    WHERE [email protected]@SPID 

он расскажет вам, кто блокирует ваш запрос

+0

Прошу прощения, это не возвращает никаких строк! – David

+0

, то в этой базе данных нет активности, удалите 'WHERE', и вы увидите строку для этого фактического запроса. Откройте несколько окон SSMS, запустите медленный запрос в одном окне, а затем быстро измените это окно и запустите этот запрос, вы можете увидеть строки, затем –

0

Независимо от любых других DB-определенное поведение, вы должны откатить транзакция сразу после ошибки. Это не должно оставлять ничего закрытого.

+0

Я работал (как разработчик) с базами данных в течение многих лет, и я всегда думал, что транзакции были свернуты автоматически, если ошибки базы данных. Забавное время, чтобы узнать, как я ошибался! – David

+0

Спасибо Диего. Я обновил свой код репозитория соответствующим образом, и теперь таблица не заблокирована после ошибок базы данных. – David

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