从多线程应用程序有效地写入db

时间:2013-08-03 18:35:47

标签: c# .net sql-server database multithreading

我有一个服务器应用程序,它从客户端接收必须存储在数据库中的数据。

与ServiceStack进行客户端/服务器通信,并且对于每个客户端调用,可以写入1个或多个记录。

客户端无需等待写入数据或知道数据是否已写入。

在我的客户站点,数据库有时可能在短时间内不可用,因此我想重试写入,直到数据库再次可用。

我不能使用servicebus或其他软件..它必须只是我的服务器和数据库。

我考虑了两种可能性:

1)为每次调用写一个记录(或带有多个插入的记录组)的一个线程,以便在重试失败的情况下重复,直到成功为止

2)将要写入的数据加入到全局内存列表中,并使用一个后台线程连续单次调用db(带有多个插入) 您认为最有效的方法是什么?或者你有其他提案吗?

选项1更容易,但我担心有太多线程同时运行,特别是如果数据库不可用。

如果我按照第二条路线行事,我的想法是:

1)客户端打开的每个服务器线程锁定全局列表以插入1个或多个记录以写入数据库,释放锁定并关闭

2)后台线程锁定具有例如50条记录的全局列表,将深层副本复制到临时列表,解锁全局列表

3)服务器线程继续将数据添加到全局列表,同时后台线程尝试写入50条记录,重试直到成功

4)当后台线程设法写入时,它再次锁定全局列表(可能现在有80条记录),删除已写入的前50个,一切都重新开始

有更好的方法吗?

---------编辑---------- 我的问题是我不希望客户端以任何方式等待,甚至不希望将要发送的记录添加到阻止列表(当写入线程写入或尝试写入时发生这种情况)列表到DB)。 这就是为什么在我的解决方案中我锁定列表只是为了将列表复制到将写入db的临时列表。 我只是想知道这是否是疯狂的,并且有一个更简单的解决方案,我没有关注。

2 个答案:

答案 0 :(得分:1)

我对这个问题的理解如下:
1.客户端发送要插入数据的数据
2.服务器接收数据并插入到数据中 3.客户端不想知道数据是否正确插入

在这种情况下,我建议,让服务器创建一个单独的Queue,它保存要插入到DB的数据,让接收线程只接收来自客户端的数据并插入到内存队列中,这个队列可以被另一个小心的队列清空写入DB以保持。
您甚至可以使用基于文件的队列或优先级队列,或仅使用内存中队列来临时存储记录。

答案 1 :(得分:0)

如果使用.Net线程池,则无需担心创建太多线程,因为为您管理线程生存期。

Task.Factory.StartNew(DbWriteMethodHere)

如果你想变得更聪明,你可以将你想要提交的记录添加到BlockingCollection - 然后让一个线程做BlockingCollection<T>.Take(50),这将阻塞,直到有足够大的批量提交。