2013-08-03 2 views
0

У меня есть серверное приложение, которое получает данные от клиентов, которые должны храниться в базе данных.Напишите db эффективно из многопоточного приложения

Клиентская/серверная связь производится с ServiceStack, и для каждого вызова клиента может быть записано 1 или более записей.

Клиентам не нужно ждать данных, которые нужно записать, или знать, были ли данные записаны.

На моем сайте клиента база данных иногда может быть недоступна в течение коротких времен, поэтому я хочу повторить запись до тех пор, пока база данных не будет доступна снова.

Я не могу использовать служебную шину или другое программное обеспечение ... это должен быть только мой сервер и база данных.

я рассмотрел две возможности:

1) пожар поток для каждого вызова, чтобы написать отчет (или группу записей с многократным вкладышем), что в случае отказа повторных попыток, пока он не имеет успеха

2) enqueque данные, которые должны быть записаны в глобальном списке в памяти, и иметь один фоновый поток для непрерывного выполнения одного вызова в db (с несколькими вставками) Что вы считаете наиболее эффективным способом сделать это? или у вас есть другое предложение?

Вариант 1 проще, но я беспокоюсь, что слишком много потоков работает в одно и то же время, особенно если db становится недоступным.

В случае, если я буду следовать за второй путь, моя идея:

1) каждый сервер поток открыт клиент блокирует глобальный список для вставки 1 или несколько записей для записи в БД, снять блокировку и закрывает

2) фоновый поток блокирует глобальный список, который имеет, например, 50 записей, делает глубокую копию списка временного, отпирает глобальный список

3) нить сервера продолжает добавлять данные в глобальный список, тем временем фоновый поток пытается записать 50 записей, повторять попытку до тех пор, пока он не достигнет успеха

4), когда фоновый поток удается писать, он снова блокирует глобальный список (который, возможно, сейчас имеет 80 записей), удалите первую 50, что было написано, и все начинается снова

Есть ли лучше способ сделать это?

--------- EDIT ---------- Моя проблема заключается в том, что я не хочу, чтобы клиент мог ждать, даже не для добавления запись, подлежащая отправке в заблокированный список (это происходит, когда записывающий поток пишет или пытается записать список в БД). Вот почему в моем решении я блокирую список только за время, чтобы скопировать список во временный список, который будет записан на db. Мне просто интересно, если это сумасшествие, и есть гораздо более простое решение, за которым я не следую.

+2

'На моем сайте клиента база данных иногда может быть недоступна для коротких времен' - вы подумали об исправлении этой проблемы? –

+0

Рассматривали ли вы очередь сообщений (например, MSMQ или RabbitMQ)? – lukiffer

+0

Я бы попробовал BlockingCollection http://msdn.microsoft.com/en-us/library/dd997371.aspx – Paparazzi

ответ

0

Если вы используете пул .Net Thread Pool, вам не нужно беспокоиться о создании слишком большого количества потоков, так как управление жизненным циклом потоков выполняется для вас.

Task.Factory.StartNew(DbWriteMethodHere) 

Если вы хотите быть умнее, вы можете добавить записи, которые вы хотите взять на себя обязательство BlockingCollection - и затем нить сделать BlockingCollection<T>.Take(50), который будет блокировать до тех пор, пока не будет достаточно большая партия совершить.

+0

, но затем, пока поток отправляет данные в db, основной поток не может добавить данные в коллекцию, поэтому мое приложение заблокировано, правильно? –

+0

и в любом случае, если БД заблокирован, не будет стрелять 1000, например потоки создают проблемы? –

1

Мое понимание этой проблемы заключается в следующем:
1. Клиент посылает данные для вставки в БД
2. Сервер принимает данные и вставляет к БД
3. Клиент не хочет знать, данные вставлены должным образом или нет

В этом случае я предлагаю: Пусть сервер создаст единую очередь, которая хранит данные для вставки в БД, позволяет получать поток, просто получая данные от клиента и вставляя их в очередь inmemory Queue, эта очередь может быть опустошена другим потоком, который заботится о записи в БД для сохранения.
Вы можете даже использовать очередь на очереди файлов или очередь приоритетов или просто в очереди на память для временного хранения записей.

+0

Да, это более или менее второй маршрут, который я предложил, мне было интересно, был ли другой способ –

Смежные вопросы