2017-01-15 2 views
1

У меня есть приложение, которое использует LMDB. Если несколько процессов необходимо записать в базу данных, только один из них будет разрешен для запуска одновременно и остального блока. Из-за этого я хочу переписать приложение для использования модели клиент-сервер.LMDB: Перемещение транзакций без отката всего

Если приложение написано для использования модели клиент-сервер, сервер может управлять записью, а другие процессы не будут блокироваться. Однако, если клиент сталкивается с ошибкой и должен отменить свою транзакцию, как он может откатить свои данные, не откатываясь от того, что другие клиенты написали?

Я просмотрел вложенные транзакции, но транзакции записи могут иметь только одну вложенную транзакцию. Поэтому, когда клиент может записывать свои данные во вложенную транзакцию и откатывать ее обратно, если возникает ошибка, только один клиент сможет работать одновременно. Таким образом, хотя это решает проблему отката, мы возвращаемся к проблеме, которую может написать только один клиент за раз.

Я также рассмотрел опцию MDB_NOLOCK, которая заставляет LMDB не мешать вам создавать несколько транзакций записи. При попытке совершить любую транзакцию, кроме первой, она вернет ошибку. Возможно, клиенты могут объединить свои записи в свои транзакции, и когда они будут готовы к фиксации, сервер будет выгружать записи в первую транзакцию записи, но это хакки, и я уверен, что это НЕ то, что разработчики намеревались сделать для использования.

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

Есть ли другие способы, позволяющие различным процессам писать в базу данных, имея возможность откатывать данные одного клиента, не откатывая все?

ответ

0

Нет непростого решения проблемы, которую вы ставите.

Можно записывать транзакции произвольно глубоко, но, как вы говорите, это не поможет вам достичь большей пропускной способности, потому что вы все равно будете ограничены одним потоком для этой транзакции записи. Поэтому для большинства целей и целей, если вы используете LMDB, поскольку он был предназначен для использования, вы будете иметь только один поток, выполняющий операции записи в базе данных.

Вы спросили, как вы можете прервать чью-то транзакцию, не откатываясь от txn других. Это в значительной степени не является проблемой, поскольку, как уже упоминалось выше, у вас будет только одна транзакция записи в данный момент. Если вы завершаете в конце запроса и начинаете новую транзакцию в начале следующего запроса, ваши транзакции записи не будут перекрываться. После того, как вы перенесите первую транзакцию, вы не сможете ее прервать, но если ваш клиент сообщает серверу об отмене запроса до его совершения, ваш сервер может прервать его. И когда он прерывается, состояние базы данных прибегает к состоянию, в котором оно было, когда эта транзакция была запущена. Он не потеряет никаких других транзакций и не потеряет изменения, созданные другими запросами.

Как вы указываете, вы можете выполнить несколько запросов на запись в одну запись txn. Вы можете обрабатывать некоторые из этих запросов на запись в других потоках, но все Любые вызовы API LMDB все равно должны выполняться в исходном потоке. И если вы попытаетесь посвятить поток каждому запросу для достижения некоторого параллелизма, вам все равно нужно будет убедиться, что запросы взаимно совместимы и не мешают друг другу. И если один из этих запросов запущен, вам придется прервать транзакцию и, возможно, перезапустить транзакцию. Когда вы перезагружаете транзакции, вы, вероятно, включите только те запросы, которые не попали в неприятности. - Это все возможно, но только у вас достаточно знаний о вашем приложении, чтобы знать, будет ли это значительно улучшать производительность и будет стоить ваших усилий.

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