twobomb, на c# можно запросто поставить lock и клиент "висит" в ожидании при обработке запроса сервером. Использование транзакций в бд - это другое. Не думаю, что это самая простая задача, учитывая что тестировать ее не так просто.
twobomb, о том и пишу, что вопрос нетривиальный, т.к. является проблемой многопоточного программирования. Но здесь добавляется тот факт, что синхронным нужно зделать запрос к серверу, что не так сложно, но приведет к тому, что при 1000 одновременных запросов сервер просто упадет - это критическое место. Поэтому и задан вопрос.
Дмитрий, Я не видел вашего ответа, т.к. думал над этим более 20-ти минут.
Непонятно, но код обработчика вызывается дважды. Но заметил: когда возвращаем новый экземпляр todo, то значение старого todo не меняется, т.е. всегда меняется complete для старой ссылки todo, что означает что обработчик выполняется дважды для старого состояния. Отсюда и думаю.
Ну на скорость то да - тут опыт нужен, но в целом верстку по сложности не сравнить с некоторыми задачами программирования: ИИ, игры (multiplayer), deep learning, etc.