Как разрешить конфликт данных при одновременном редактирование данных несколькими пользователями?
Здравствуйте, бородатые товарищи программисты. Пишу тут для себя один проект, и вот возникла некоторая архитектурная задача, решения которой я пока не нашёл. Не отрицаю, может плохо искал и тупил, но уж как есть, так есть.
Опишу суть: есть некоторый сервер и некоторое количество клиентов. Клиент может принять данные от сервера, возможно, отредактировать их и отправить обратно. Сервер может брать данные из внутреннего хранилища (БД) и отправлять эти данные клиентам (возможно многим одни и те же, шаринг присутствует), после чего принимать эти данные и писать их в БД. Ну, стандартная архитектура в общем. И всё хорошо, пока >2 клиентов не попытаются отправить изменённые одни и те же данные.
Пример: на сервере в БД есть ячейка со строкой "Hello, Habr!". Подключаются два клиента и забирают эту строку с сервера. Первый клиент изменяет строку на "Hello, Habrahabr!", второй на "Hello, Habr and Geektimes!", после чего они оба отправляют их на сервер, где эти строки сохраняются в условную временную таблицу. Как серверу разобраться, что положить в основную ячейку в БД?
При этом информация не должна быть утеряна. Можно, конечно, уведомить пользователя о конфликте версий и оставить трудный выбор на него, но ведь меньше окошек и надоедающих предупреждений = лучше.
Какие у кого есть идеи? Буду благодарен.
P.S. Сервер - C# под .NET 4.5, потом будет C++11. Клиент - С# под .NET 4.5 и Java.
P.S.S. Быть может, подойдёт решение подобной проблемы в Git или MS Word? Есть информация, как реализовано?
Владимир Грабко: Ну нельзя же просто взять и положить в БД "Hello, Habr and Geektimes!" и забыть про изменения 1-ого клиента. Получается, проблема в том, что второй пользователь редактирует уже устаревшие (на момент отправки их на сервер) данные, потому что 1-ый уже поменял оригинальные данные. Я понимаю, что при таких условиях непомерно усложняется вся система, но без этого то тоже проблематично.
Сергей Сергеев: в принципе для себя, ну и ещё для пары друзей. Так то можно было бы сделать доступ к данным (чтение/запись) только для одного пользователя, а всем остальным доступ только на чтение, но ведь клиент может быть поднят на нескольких устройствах (пк+android). Потерянные данные всегда не хорошо)
Сергей Сергеев: нет конечно) Вариант с блокировкой не подойдёт по определению. Делаю на коленке для себя записки. Да, в курсе, что есть Evernote, Keep, OneNote и пр., но мне ни один из них не нравится. Ну и плюс саморазвитие.
{
"text" : "то что редактируете",
"text_update" : "на что редактируете"
}
Потом сравнивайте text с тем что в базе. Если совпадает то обновляете значение и возвращайте http статус 200. Если нет то отправляете http статус 205 Reset Content (говорит о том что надо обновить документ).
Потом на клиенте смотрите какой статус отправил сервер. Если 200 то говорите что мол всё хорошо запись обновлена. Если 205 то говорите что эти данные изменились
А чтобы отследить изменение строки в реальном времени можно заюзать веб сокет
Да, как вариант. Но тогда уж лучше отправлять оригинальный текст в виду какого-нибудь md5 хэша для экономии трафика. Но это уже оптимизации... Одна проблема - окошки, окошки, много окошек, которые достают пользователя.
TeslaCtroitel: так вы на сервере должны будете сделать хеш нового текста. А если у вас текст пару тысяч слов то сколько вы будете делать md5 хеш? А если у вас 500к запросов в минуту? а?
Формулируете алгоритм, по которому сервер должен решать что записать, реализовываете, PROFIT. Только вы не сможете сформулировать, поэтому это не задача для сервера.
Да проблема в том, как сформировать результирующую строку из строк от клиента 1 и 2, не потеряв первого и второго. По идее та же самая проблема происходит в Git, когда два программиста взяв старые версии одного файла изменяют в нём разные строки и коммитят файл обратно на сервер. Как Git сливает изменения двух программистов в один файл, не затирая изменения?