1

开发人员正在寻找最佳方法来识别特定线程内特定事务的死锁。我们遇到了死锁错误,但这些在 FB 2.0 中非常普遍

发生死锁,它们导致客户端和数据库之间的数据库连接中断。

  • 我们将实时(每秒一次)数据发送到数据库。
  • 我们打开一个由大约 30 个线程组成的线程池,并使用它们来摄取数据(大约每秒 1-2 kB)。
  • 有时数据库只能占用这么多,以至于我们使用池中的下一个线程来尽可能保持流最新。

除了达到最大线程数和中断连接之外,有时这会产生死锁。

因此,我们真的需要就这是否是每秒摄取这么多数据的最佳方法提出意见。我们有多达 100 个这些客户端同时访问数据库。
平均每天的交易量约为 1.5 到 180 万笔。

4

3 回答 3

1

在 Firebird 2.1 中,有针对表、连接和事务的新监控功能,也许可以帮助您(如果您可以升级)。请参阅 README.monitoring_tables.txt。

例如,获取活动语句:

SELECT ATT.MON$USER, ATT.MON$REMOTE_ADDRESS, STMT.MON$SQL_TEXT, STMT.MON$TIMESTAMP
FROM MON$ATTACHMENTS ATT 
JOIN MON$STATEMENTS STMT ON ATT.MON$ATTACHMENT_ID = STMT.MON$ATTACHMENT_ID
WHERE ATT.MON$ATTACHMENT_ID <> CURRENT_CONNECTION AND STMT.MON$STATE = 1
于 2008-09-15T14:41:41.953 回答
1

我不知道识别特定线程或语句的特定方法。我不得不多次处理 FB 死锁。您可能有两个头试图更新某个表中的同一行,但它们是在单独的事务中进行的。

我发现最好的解决方案是设计一些东西,这样线程就不必更新任何其他线程可能更新的行。有时这意味着拥有一个只存在用于更新公共表/行的线程。工作线程向该线程发送消息。(该消息可以通过另一个表完成。)

我们在该领域的许多系统中运行 FB,这些系统会生成交易(不是每天数百万),我们发现一旦设计正确,FB 就会坚如磐石。

于 2008-09-15T13:48:26.903 回答
-1

我的建议是编写一个 3 层应用程序,将对数据库的所有访问(插入)序列化到单个线程(其他线程只会在队列上堆叠数据)并使用 Firebird 嵌入式(这要快得多,因为它消除了 TCP/ IP 开销)。

除了避免死锁之外,这种方法还可以让您监控队列并查看系统如何应对负载。

于 2008-09-29T17:13:17.180 回答