使用Firebird识别线程中的死锁

时间:2008-09-15 13:36:03

标签: database multithreading deadlock firebird pool

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

发生死锁,它们导致客户端和数据库之间的数据库连接出现故障。

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

有时,除了达到最大线程数并断开连接外,还会产生死锁。

因此,如果这是每秒摄取此数据量的最佳方法,我们真的需要一些意见。我们在这些客户端同时有多达100个命中数据库 平均交易量约为每天150万到180万。

3 个答案:

答案 0 :(得分:1)

我不知道识别特定线程或语句的具体方法。我不得不多次处理FB僵局。您可能有两个尝试更新某个表中同一行但需要在单独的事务中执行此操作的主题。

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

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

答案 1 :(得分: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

答案 2 :(得分:-1)

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

除了避免死锁之外,这种方法还允许您监视队列,看看系统如何处理负载。