Размышления о транзакциях

phprus

Moderator
Команда форума
grigori
объяснить на конкретном примере, конечно, могу
Расскажи пожалуйста, как в банках все на самом деле устроено. Мне эта тема тоже интересна.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
1. логика работы с базой реализуется атомарными операциями и выносится в хранимые процедуры, которые, кроме обеспечения целостности, еще и доступ контролируют, и логи пишут, и расчеты нужные выполняют
2. операции не выполняются автоматически (как на freelance.ru)
под каждый платеж распечатывается ордер/ведомость, подписывается исполнителем, начальником, контролером, и так же в опердне ими же помечается,
а внешние платежи еще проверяются каким-нибудь казначейством, потом руками отдельным операционистом вбиваются в систему центробанка или SWIFT (как это в центробанке - не знаю)

вообще, на нижнем уровне почти не пишут - обычно покупается готовая система, на которую дописывается отчетность, интерфейсы и т.п. на основе существующего API
скорость исполнения - последнее, о чем думают, что потом создает проблемы "на местах"
 

akd

dive now, work later
Команда форума
grigori, по первому пункту вопросов нет :)
по второму, это не везде так. если транзакция попадает под внутренние критерии то проводится автоматом. если внешняя транзакция, то максимально обрабатываются, чтобы операционисту нужно было делать минимум движений (справочники свифтов и т.д.).
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
"минимум движений" и "автоматом" - очень разные понятия
в контексте топика я говорю о том, что в банках платежи обрабатываются людьми, и ситуация, когда в одной транзакции в базе делаются все запросы от сабмита клиентом формы в клиент-банке до зачисления на счет получателя - не бывает в принципе
 

akd

dive now, work later
Команда форума
grigori, ну я тебе о том и говорю, что уже бывают. хотя я не в курсе ситуации в СНГ, говорю про ЕС. транзакции по внутренним счетам - полный автомат. внешние обработаны настолько, чтобы контроллер мог только нажать кнопку "Confirm" :)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
в любом случае, запросы к таблицам никто не пишет :)
и транзакции не стартует
все через хранимые процедуры, в которых транзакции стартуют и коммитят, если надо (хранимая процедура сама по себе атомарна)
и уж точно не на MySQL :)
 

akd

dive now, work later
Команда форума
это да :) но у автора свое видение, у него есть на это право :)
 

Sluggard

Новичок
Представте: юзер переводит деньги со своего счёта на другой счет и, допустим, транзакция успешно коммитится, а время date_last_visit не обновляется. Но у Вас это второстепенный запрос, поэтому Вам на него насрать.
В начале приложения происходит аутентификация пользователя. Тогда же делаешь и апдейт date_last_visit. После этого обрабатывается основной запрос пользователя на перевод денег. Отдельной транзакцией. Потому что это не связанные функции приложения, могут жить отдельно друг без друга и не нарушают целостности данных.

что Вы будете делать, если человек переведёт деньги не заходя в систему (на самом деле он заходил, но у него отвалился "второстепенный" запрос на обновление date_last_visit)
Ничего. См. выше. Может быть обратная ситуация - заходил, но деньги не перевел. На это дружно кладем.

Что теперь Вы думаете про "второстепенные запросы"?
Что и раньше - они тоже могут быть объеденены в транзакцию, если это требуется для сохранения целостности. Но не для какого другого случая. Объединяя запросы в транзакцию, ты не должен задумываться в какую категорию их относить: к "важным" или "второстепенным". Целостность - вот твоя цель.

Протестировал на одной таблице. Первый процесс меняет date_last_visit для 23-его юзера, второй процесс меняет для 58-ого.
Блокируются разные записи. Зачем тестировал?

я проверил и скорость в 109 раз быстрее
Уже слышали. Что выполняет твоя программа, что ты сопоставил 1000 апдейтов в одной транзакции против 1000 апдейтов в разных. Почему не миллион? Будет еще быстрее.

В случае если оба процесса изменяют одну и ту же запись, то второй процесс ждёт коммита со стороны первого.
Это и есть время блокировки. Его и сравнивай.

Лиш в редких случаях, когда разные юзеры выполняют операцию над одним и тем же, придётся подождать (хотя в Вашем подходе им тоже придётся подождать). Так и чем же глобальные транзакции хуже ядерных?
Время блокировки дольше.

В рейльно же CMS/CMF с развитой MVC и прочей структурой выше написанный мною код превращается в одну глобальную транзакцию.
Что такое "развитая MVC"? Какие CMS/CMF ты относишь к реальным? И главный вопрос - зачем им нужны глабальные транзакции?

-~{}~ 17.09.10 19:52:

глобальная транзакция плоха тем, что не делит данные по степени важности - если проходят деньги и есть нормальный коммит - это прекрасно и должно отработать независимо от следующих операций, которые могут быть второстепенными... лучше сразу это понять, имхо
Не надо выдумывать. Нет запросов важных или второстепенных. Запрос рассматривается в рамках определенной задачи. И в рамках этой задачи (пусть то будет перевод денег или журнал посещений) все запросы последовательны и одинаково важны. Они решают конкретную задачу. Если было бы все так, как ты говоришь, запросам раздавались бы приоритеты. И в соответствие с этими приоритетами БД решала бы, в какой очередности выполнять запросы. Этого нет. Сегодня еще нет.
 

Вурдалак

Продвинутый новичок
Автор оригинала: Sluggard
Этого нет. Сегодня еще нет.
— встреваю в середину дискуссии, но некие приоритеты всё-таки есть. Тот же UPDATE может использоваться с LOW_PRIORITY.
 

Sluggard

Новичок
Автор оригинала: Вурдалак
— встреваю в середину дискуссии, но некие приоритеты всё-таки есть. Тот же UPDATE может использоваться с LOW_PRIORITY.
Слово "некие" здесь ключевое?
1. Работает только с LOCK TABLES/UNLOCK TABLES. Транзакции отпадают. Но мы ведь говорим именно о них?
2. Не позволяет, например, один update сделать приоритетнее другого. А нам именно это и надо, чтобы указать, какие update'ы "важны", какие "второстепенны".
3. Приоритеты не работают в рамках одного потока; т.к. все запросы выполняются последовательно.

Что дает расставлять эти приоритеты? Да ничего. Сделать select приоритетнее updat'а в запросах из разных потоков при заблокированной таблице. Круто. Но это нам не надо.
 
Сверху