Мое предложение будет похоже на ваше первое. Когда первый пользователь (Боб) открывает документ, он получает блокировку, чтобы другие пользователи могли только читать текущий документ. Если пользователь сохраняет документ во время его использования, он сохраняет блокировку. Только когда он выходит из документа, он разблокируется, и другие люди могут редактировать его.
Если второй пользователь (Кейт) открывает документ, когда у Боба есть блокировка, Кейт получит сообщение о том, что документ недоступен для редактирования, но она может прочитать его, пока не будет снята блокировка.
Так что же происходит, когда Боб получает блокировку, возможно, сохраняет документ один или два раза, но затем выходит из приложения, оставляя блокировку заблокированной?
Как вы сказали сами, требование клиента с блокировкой отправлять пинг с определенной частотой, вероятно, является наилучшим вариантом. Если вы не получаете пинг от клиента в течение определенного времени, это фактически означает, что его клиент больше не отвечает. Если это веб-приложение, вы можете использовать JavaScript для пингов. Последний сохраненный документ снимает блокировку, и теперь Кейт может его получить.
Пинг может содержать имя документа, на котором клиент заблокирован, и сервер может рассчитать, когда был получен последний пинг для этого документа.