BDE, Delphi, ODBC, собственный клиент SQL и мертвая блокировка

У нас есть некоторый код Delphi, который использует BDE для доступа к SQL Server 2008 через драйвер ODBC для собственного клиента SQL Server (версия 2005 года). Наша проблема заключается в том, что у нас возникают проблемы с тупиком в цикле, выполняющем вставки в несколько таблиц.

Весь цикл выполняется внутри [TDatabase].StartTransaction. Глядя на SQL Server Profiler, мы ясно видим, что в какой-то момент цикла SPID (ID сеанса?) Меняются, и тогда мы, естественно, заходим в тупик. (Оба SPID делают вставки в одну таблицу)

Кажется, что BDE в какой-то момент устанавливает второе соединение с БД...

(Хотя я хотел бы пропустить BDE, в настоящее время это невозможно.)

Кто-нибудь с опытом поделиться?

3 ответа

Если ваше приложение многопоточное: BDE не является потокобезопасным. Вы должны использовать отдельный сеанс BDE (явно созданный экземпляр TSession) для каждой темы; глобальный Session созданного автоматически для основного потока недостаточно. Кроме того, все компоненты доступа к базе данных (TDatabase, TQueryи т. д.) могут использоваться только в контексте потока, где их соответствующий экземпляр TSession был создан.

В установке ODBC проверьте, настроен ли драйвер SQL Server для создания пула соединений. Кажется, что установка Native Client активирует его по умолчанию... (По крайней мере, моя установка имела активный пул соединений, и я не активировал его).

Возможно, это слишком поздно для спрашивающего, но, возможно, это поможет другим.

Каждый раз, когда появляется курсор, который не закрывается, комбинация BDE/ODBC устанавливает новое соединение для последовательных запросов. "Смена спида", вероятно, является результатом незамкнутого курсора.

Чтобы решить эту проблему, вы должны найти BDE-компонент, который вызвал этот открытый курсор. Затем вы вызываете метод, который в конечном итоге закроет курсор (TTable.Close, TTable.Last...).

После этого "смена спида" должна исчезнуть и, следовательно, тупик.

Несколько советов, чтобы найти этот компонент:

  • Во время блокировки выполните следующую инструкцию (например, с помощью Management Studio):EXEC sp_who2,
  • Посмотри в колонке BlkBy, В заблокированном соединении есть номер.
  • Этот номер является spid (Идентификатор процесса сервера) блокирующего соединения.
  • Затем вы выполняете DBCC INPUTBUFFER(spid),
  • В колонке EventInfo Вы найдете SQL-оператор, выданный вашей программой.
  • С этой информацией вы сможете найти BDE-компонент, который вызывает у вас проблемы.
Другие вопросы по тегам