3

我们有一些 Delphi 代码使用 BDE 通过 SQL Server Native Client ODBC 驱动程序(2005 版)访问 SQL Server 2008。我们的问题是我们在对多个表进行插入的循环中遇到了一些死锁问题。

整个循环在 [TDatabase].StartTransaction 中完成。查看 SQL Server Profiler,我们清楚地看到,在循环期间的某一时刻,SPID(会话 ID?)发生了变化,然后自然而然地以死锁告终。(两个 SPID 都对同一个表进行插入)

似乎 BDE 在某些时候会与 DB 进行第二次连接......

(虽然我很想跳过 BDE,但目前不可能。)

有经验的可以分享一下吗?

4

3 回答 3

1

如果您的应用程序是多线程的:BDE 不是线程安全的。您必须为每个线程使用单独的 BDE 会话(显式创建的实例TSession);为主线程自动创建的全局Session是不够的。此外,所有数据库访问组件(TDatabaseTQuery等)只能在TSession已创建其对应实例的线程上下文中使用。

于 2010-03-24T10:38:28.870 回答
1

如果 SQL Server 驱动程序配置为执行连接池,请在 ODBC 安装中验证。似乎 Native Client 安装默认激活它......(至少,我的安装激活了连接池并且我没有激活它)。

于 2010-07-22T17:48:19.957 回答
0

对于提问者来说,这可能为时已晚,但也许对其他人有帮助。

每次有游标未关闭时,BDE/ODBC 组合都会为后续查询建立新连接。“spid 更改”可能是非关闭游标的结果。

要解决这个问题,您必须找到导致这个仍然打开的游标的 BDE 组件。然后调用一个最终会关闭光标的方法(TTable.Close... TTable.Last)。

之后,“spid change”应该消失,因此陷入僵局。

找到该组件的一些提示:

  • 在锁定期间,执行以下语句(例如使用 Management Studio) EXEC sp_who2:.
  • 在列中查找BlkBy。被阻止的连接中有一个数字。
  • 这个数字是spid阻塞连接的(服务器进程 ID)。
  • 然后你执行DBCC INPUTBUFFER(spid).
  • 在列EventInfo中,您将找到程序发出的 sql 语句。
  • 有了这些信息,您应该能够找到导致您遇到问题的 BDE 组件。
于 2014-08-27T16:10:28.473 回答