Почему QuickBooks нельзя хранить на Google Drive для нескольких пользователей
Прежде чем углубляться в детали, важно понять, что речь идёт об общей концепции, которую можно сформулировать так: “почему приложения типа клиент/сервер или приложения с общим файлом базы данных нельзя хранить в синхронизируемом хранилище (например, Google Drive, DropBox, NextCloud и т.д.), если доступ не ограничен одним пользователем?” QuickBooks использует механизм общего файла базы данных, типичный для приложений эпохи 1980-х годов, когда один файл или набор файлов открывается в совместный доступ через файловый механизм, а отдельные копии приложения обращаются к этому файлу для его изменения. Google Drive — это механизм синхронизированного хранилища: он копирует данные из одного места в другое. Пользователи, работающие с одним файлом одновременно, могут (и нередко это происходит) перезаписывать изменения друг друга, при этом предполагается, что такие конфликты будут вручную устранены позднее, проигнорированы или что пользователи будут ограничены в одновременной работе.
Для некоторых типов многопользовательских приложений синхронизируемое хранилище можно задействовать, но лишь в тех случаях, когда приложение способно блокироваться системой хранения так, чтобы разрешать изменения только тогда, когда их не делает никто другой. Это требует уровня интеграции, недостижимого при использовании универсальной синхронизации файлов. Большинство систем, реализующих подобное, используют механизм синхронизации, встроенный в уровень базы данных или приложения, а не универсальный, действующий вслепую. Чтобы сохранить целостность данных при синхронизированном хранилище, необходимо, чтобы только один пользователь редактировал файл, дожидался, пока все возможные пользователи получат обновления после его “сохранения”, и только затем другой пользователь мог открыть файл для редактирования. Таким образом, одновременно работать с файлом может лишь один пользователь, и перед открытием файла он должен получить обновления от других пользователей. Иначе система должна спрашивать пользователей, какие изменения сохранять, а какие отклонять — в каждом отдельном случае.
Этот процесс обеспечения целостности в принципе неприменим к файлу базы данных в реальных условиях. Файл предназначен для постоянного открытия и доступа, а не для того, чтобы быстро открыть, отредактировать и сохранить. Сохранение также не является ручной операцией и не всегда предсказуемо. Обычно предполагается, что сохранение происходит непрерывно во время работы, однако кэширование может сделать даже эти операции сохранения невозможными для ручного контроля. Но это необходимо из соображений производительности.
Путаница часто возникает потому, что один пользователь, не опасаясь одновременного доступа другого пользователя, может использовать синхронизированное хранилище — например, Google Drive или Apple iCloud — в качестве механизма резервного копирования (оно просто автоматически создаёт удалённую копию) и/или как способ перемещения файла, чтобы единственный пользователь мог работать сначала с одного места, а затем с другого, без необходимости вручную переносить файл. Если этот пользователь достаточно выдерживает паузу при смене рабочего места, чтобы убедиться, что кэш сброшен, синхронизация и блокировки завершены, или убеждается, что первый экземпляр приложения закрыт, можно считать систему относительно безопасной (хотя абсолютной гарантии нет — механизм несёт минимальный риск состояний гонки и в этом случае). Поскольку “есть способ” безопасно использовать синхронизированное хранилище с приложением в однопользовательском режиме, многие нетехнические специалисты по бухгалтерии или финансам ошибочно предполагают, что одновременный многопользовательский доступ, который принципиально отличается, тоже будет работать. Однако это невозможно.
Происходит следующее: возникает состояние гонки между несколькими пользователями, и никогда нельзя быть полностью уверенным, что оно не произошло. Иногда данные просто окажутся некорректными и будет очевидно, что состояние гонки имело место — цифры окажутся совершенно неверными. Но чаще некоторые транзакции просто исчезнут, даже после того как они были проверены.
Приведём пример. Пользователь 1 находится дома и вводит новый чек в QuickBooks. Это изменение начинает сохраняться на локальном компьютере, а после завершения начинает передаваться на Google Drive в облако (онлайн). Пользователь 2 находится в офисе и в это время начинает вводить оплату по счёту клиентом. Файл данных QuickBooks у пользователя 2 открыт и не может быть перезаписан во время использования, поэтому копия, отправляемая на Google Drive, не может попасть к пользователю 2. Когда пользователь 2 сохраняет своё изменение, его копия тоже хочет отправиться на Google Drive. Теперь Google Drive должен что-то сделать с двумя документами, которые изначально были одинаковыми, но теперь содержат два радикально разных изменения, причём ни одна копия не содержит оба. Объединить их невозможно, поэтому можно либо принять версию пользователя 1 как основную и отклонить изменения пользователя 2 (приоритет первого), либо принять изменения пользователя 2 и отклонить изменения пользователя 1 (приоритет последнего). Или, конечно, отклонить все изменения и не принять ни одного. Ни в одном случае финансовые транзакции всех пользователей не сохраняются, даже после того как те сохранили их локально. Либо пользователь 1, либо пользователь 2 (а возможно, оба) обнаружат, что данные, которые они считали сохранёнными, внезапно исчезли. С увеличением числа пользователей проблема только усугубляется.
Часть проблемы в том, что при работе на уровне файлового доступа и синхронизации данных на уровне полного файла невозможно заблокировать только одну запись или строку, разделить транзакции или объединить изменения. Файл — единое целое, и он изменился. Всё или ничего. Отдельные экземпляры QuickBooks не могут общаться друг с другом напрямую или через файл базы данных, чтобы координировать операции записи, сохранения, чтения и т.д. для обхода этой проблемы. Они действуют вслепую и не могут знать, что другие приложения одновременно пытаются работать с тем же файлом, потому что у каждого своя уникальная копия файла — нет ничего “общего” между ними, что позволяло бы коммуникацию. Копии не связаны между собой, никакого квантового состояния здесь нет. К этому добавляются потенциальные проблемы, когда один или несколько экземпляров приложения используются при медленном или нестабильном интернет-соединении или, что ещё хуже, когда экземпляр находится в офлайн-режиме. Могут накопиться изменения за часы или дни, которые придётся перезаписывать при синхронизации. Чаще речь идёт не о миллисекундах, а о нескольких днях данных.
Способ решения этой проблемы при работе с локально общими файлами многогранен. Во-первых, существует только один файл, а не его копии. Поэтому все изменения доступны всем экземплярам приложения одновременно и мгновенно. Когда один экземпляр приложения собирается записать данные в файл, он использует механизм блокировки и оповещения, аналогичный тому, как кластерные файловые системы позволяют работать SAN-системам: он сигнализирует другим экземплярам приложения о том, что выполняется изменение и им нужно подождать его завершения, а затем обновить свою копию данных перед продолжением. Только один экземпляр может выполнять запись, все остальные ждут. Состояний гонки не возникает, поскольку блокировка устанавливается перед началом и снимается по окончании. Все экземпляры функционируют только при условии текущей доступности данных: при потере соединения они не могут продолжать работу — критически важный механизм защиты целостности данных. Некоторые приложения развивают этот механизм до ещё более высокого уровня, добавляя прямые (а не через общий файл) каналы связи для ускорения процесса и повышения производительности. Но немногие заходят так далеко, поскольку на этом уровне, как правило, проще полностью перейти на современное приложение, чем пытаться натянуть современные многопользовательские системы на давно устаревшие архитектуры.
Надеемся, это прояснило, почему бухгалтеры нередко думают, что синхронизированные файлы будут работать, и почему они часто утверждают, что это “работало у меня”, хотя правильнее было бы сказать “мне повезло” или “я использовал совершенно другой сценарий, неприменимый к многопользовательской среде”. А также почему Google Drive, NextCloud, iCloud, DropBox и другие сервисы вполне можно использовать совместно с QuickBooks и другими устаревшими приложениями для резервного копирования и передачи данных, но их нельзя рассматривать как средство организации многопользовательского доступа — они просто не способны обеспечить целостность данных в этом случае.