- 1
- 2
- 3
- 4
Функция ПеревестиДеньги(СчетИсточник, СчетПолучатель, Сумма)
СнятьСоСчета(СчетИсточник, Сумма);
ПополнитьСчет(СчетПолучатель, Сумма);
КонецФункции
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
−93
Функция ПеревестиДеньги(СчетИсточник, СчетПолучатель, Сумма)
СнятьСоСчета(СчетИсточник, Сумма);
ПополнитьСчет(СчетПолучатель, Сумма);
КонецФункции
Как написать эту функцию безопасно? Что делать, если ПополнитьСчет упадет с исключением, например?
Иногда хранилище поддерживает транзакции только на одном ключе за раз.
Тогда приходится писать журналируемую систему, в которую ты пихаешь запись "создать BalanceChanged [id=<uuid 1>, value=10], создать BalanceChanged [id=<uuid 2>, value=-10]", после этого рапортуешь пользователю об успехе и пытаешься применить это говно. А в фоне у тебя еще ходит разведчик журнала, который регулярно проверяет, не упал ли кто посередине операции, подбирает эти операции, создает записи, если их нет, ебаный ад, в общем.
это как это? транзакция покрывает серию действий, при чем тут ключи?
По техническим причинам в данной реализации максимальное количество действий в одной транзакции — 1
https://www.sqlite.org/transactional.html
https://www.sqlite.org/atomiccommit.html
> это как это? транзакция покрывает серию действий, при чем тут ключи?
Это так, что без транзакции один и тот же ключ могут обновить сразу несколько потребителей, что приведет к недетерменированному результату: сразу два узла кластера начнут реплицировать разные значения по всему кластеру, и какое из них выиграет, зависит от стратегии разрешения конфликтов. В случае с транзакциями такая ситуация невозможна.
Привет из двадцатого века! SQL это всего лишь язык, и распределенные хранилища появились намного раньше чем "не вчера" и "двадцать первый век". не говоря уже про распределенные транзакции.
> Это так, что без транзакции один и тот же ключ могут обновить сразу несколько потребителей
ну так бы и сказал что NoSQL. это ихняя собственная специфика реализации транзакций. которая опять таки не нова.
FoxPro - тоже NoSQL. И в нём тоже прикручивали транзакции через анус :)
народ это пытается сделать уже начиная с 70х (медленые компы и медленые стораджы связаны медлеными сетями) но результаты не поменялись. если нужна консистентность данных, тебе нужны полноценные распределенные транзакции (которые охренительно дорогие в реализации и требованиях к железу). если нужна пропускная способность - учись жить с инкрементальными апдейтами и eventual consistency, и привыкай что иногда надо будет патчить данные в ручную.
латание данных в ручную не такая больша проблема в реальной жизни, на самом деле. проблема что производители NoSQL решений в лоб не предоставляют ни каких гарантий на консистентность данных. у них просто нет того глубокого фундамента по сравнению с IMB DB2 и Oracle.
> проблема что производители NoSQL решений в лоб не предоставляют ни каких гарантий на консистентность данных.
У нас кроме AP систем еще и CP системы, если что.
... в отсутствии гарантировано надежной сети, консенсус могут настолько долго пытаться достигать, что какая другая нода опять слетить, и придётся процесс по новой начинать.
для eventual consistency и типичного уровня ренундантности в NoSQL (x3, x5, и больше) это не большая проблема. но для полноценных распределенных транзакций это весьма болезненно - учитывая что они сидят часто в тех приложениях которые ко всему прочему еще и soft real-time хотят.
хотя слышал что некоторые NoSQL халявят, и тоже split brain страдают.
> У нас кроме AP систем еще и CP системы, если что.
Не в курсе.
> для eventual consistency и типичного уровня ренундантности в NoSQL (x3, x5, и больше) это не большая проблема.
Смотря что под этим имеется в виду. AP (Available / Partition tolerant) системы и вправду могут принимать на одном узле и асинхронно реплицировать, но конфликты одновременного обновления остаются.
Но про "клиент не знает, применилась ли операция" есть самая мякотка.
Дело в том, что даже в случае с SQL сервер + клиент являются распределенной системой с 2PC. И если клиент на запрос коммита транзакции получает сообщение "разрыв сети", он не знает, применилась ли транзакция.
Такие дела.
... почему для HA (high availability), первым делом клиент/сервера учатся поддерживать сессии которые не привязаны к конкретному соединению, и после fail over умеют распозновать статус последнего обломавшегося запроса.
в дешевых решениях народ это часто делает в ручную (после переподключения, проверить прошла последняя транзакция или нет).
но например Oracle RAC (не в курсе про остальные HA RDBMS) умеет и без модификации приложения, прозрачно для приложения.(*)
> Такие дела.
You don't say?
(*) ок, они хотят модификацию приложения, но это только один глобальный on error который говорит что если соединение обламалось, то надо магический реконнект делать без сброса сессии.
Локальный write-ahead log ведут?
З.Ы. Или только тех, которые сам клиент отправлял в сессиях?
в смысле? на клиенте так или иначе должна болтаться копия данных последнего запроса - все остальное делает сервак.
с другой стороны они как я понял поддерживают опционально шаред сторадж: лог мастера после обвала подбирается хот стэндбаем, когда он становится мастером.
> Или только тех, которые сам клиент отправлял в сессиях?
Хез. Но с точки зрения расхода памяти, побочных эффектов на клиенте не наблюдалось.
Единственное что оракл открыто описывал это то что финальная точка синхронизации это коммит, и желательно мелких транзакций избегать. (Но размер транзакций уже давно конфигурируемый параметр почти у всего софта который там крутится, поэтому это не проблема.)
Но, на самом деле, это нужно, не только для алгоритмов, а чтобы знать, с кого страховку сбивать, я так понимаю.