Я рассмотрел вариант с SELECT… FOR UPDATE, которая собственно и придумана для конкуретной выборки.
пользователь А, хочет перевести деньги пользователю Б.
он делает select… for update для своей строки и потом select… for update для строки пользователя Б.
делает апдейты, и комитит изменения, освобождая тем самым строки.
Но тут возможна взаимоблокировка:
когда пользователь А хочет перевести деньги пользователю Б, а пользователь Б — наоборот, хочет перевести деньги пользователю А.
1) пользователь А блокирует запись А
2) пользователь Б блокирует запись Б
3) пользователь А пытается заблокировать запись Б, которая уже заблокирована пользвателем Б, следовательно пользователь А подвисает в состоянии ожидания.
4) пользователь Б пытается заблокировать запись А, которая уже заблокирована пользователем А,
ждет, когда она разблокируется… а она не разблокируется, потому что пользователь А ждет, когда разблокируется строка Б (смотри шаг 3).
Как этого избежать?
Я предлагаю всегда первым лочить строку с наименьшим айдишником.
Если у строки А айдишник меньше чем у Б, то её всегда лочить первой, независимо от того, какой пользователь, куда хочет перевести деньги.
TypeScript ;-)
А теперь по теме поста, я правильно понимаю, что это связано с 0.1 + 0.2 != 0.3?
Тогда чего вы ждете от других?
А если скажу добрым тоном?
А белые шляпы — это когда их сами создатели ресурса просят проверить.
К слову, они вас и не просили проверять их сайт. Давайте я вам тоже чего-нибудь хорошее сделаю, и денег попрошу.
вы так говорите, как будто я сам этот select for update придумал.
вообще-то у них в документации MySQL dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html
как раз и разбирается некий гипотетический пример c select for update
По вашей ссылке я не нашёл противоречия способу с select for update.
Только перед select for update надо отключить autocommit
Ну если можно лочить сразу две строки с помощью SELECT FOR UPDATE..., то хорошо.
пользователь А, хочет перевести деньги пользователю Б.
он делает select… for update для своей строки и потом select… for update для строки пользователя Б.
делает апдейты, и комитит изменения, освобождая тем самым строки.
Но тут возможна взаимоблокировка:
когда пользователь А хочет перевести деньги пользователю Б, а пользователь Б — наоборот, хочет перевести деньги пользователю А.
1) пользователь А блокирует запись А
2) пользователь Б блокирует запись Б
3) пользователь А пытается заблокировать запись Б, которая уже заблокирована пользвателем Б, следовательно пользователь А подвисает в состоянии ожидания.
4) пользователь Б пытается заблокировать запись А, которая уже заблокирована пользователем А,
ждет, когда она разблокируется… а она не разблокируется, потому что пользователь А ждет, когда разблокируется строка Б (смотри шаг 3).
Как этого избежать?
Я предлагаю всегда первым лочить строку с наименьшим айдишником.
Если у строки А айдишник меньше чем у Б, то её всегда лочить первой, независимо от того, какой пользователь, куда хочет перевести деньги.