0

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

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

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

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

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

我考虑了两种可能性:

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

2)将要写入的数据排入全局内存列表中,并有一个后台线程来连续地对数据库进行一次调用(使用多次插入)您认为最有效的方法是什么?或者你有其他建议吗?

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

如果我遵循第二条路线,我的想法是:

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

2)后台线程锁定具有例如50条记录的全局列表,对临时列表进行深拷贝,解锁全局列表

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

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

有一个更好的方法吗?

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

4

2 回答 2

1

My understanding of the problem is as follows:
1. Client sends a data to be inserted to DB
2. Server receives the data and inserts to DB
3. Client doesn't want to know if data is inserted properly or not

In this case, I would suggest, Let server create a single Queue which holds the data to be inserted to DB, let receive thread just receive the data from client and insert into inmemory Queue, this queue can be emptied by another thread which takes care of writing to DB to persist.
You may even use file based queue or priority queue or just in-memory queue for storing the records temporarily.

于 2013-08-03T18:54:28.623 回答
0

If you use the .Net Thread Pool you don't need to worry about creating too many threads as thread lifetime is managed for you.

Task.Factory.StartNew(DbWriteMethodHere)

If you want to be smarter you could add the records you want to commit to a BlockingCollection - and then have a thread do BlockingCollection<T>.Take(50) which will block until there is a big enough batch to commit.

于 2013-08-03T18:53:55.297 回答