[mysql] Атомная модификация таблицы: можно ли обойтись без lock tables
Использовать транзакции.
> Дело в том, что коде форума, который я модифицирую,
> не нашел ни единой блокировки таблиц.
В этом форуме тоже раньше не было.
Во-вторых, это слишком медленно, на сколько я помню.
сделай лог и вперед...
Что, если так сделать? Сначала записать в `t2_id` какое-то служебное значение, а потом поправить его, после создания записи в `table2` ?
Кстати, я так понял, что в этом форуме тоже используются блокировки для создания обсуждений?
в этом форуме на все блокировки и целостность просто положили
а инфа по средней\максимальной загрузке форума пользователями где-нить есть? =)
В этом форуме мы везде транзакции поставили.
А я думаю, что это иногда так медленно грузится. Можно в часы пик снимать транзакции?
Да, запрещать флудить, транзакций не будет.
нельзя допустить, чтобы во второй таблице остались лишние записи, либо чтобы в первой таблице были битые ссылкиА объясни, зачем тебе нужна целостность в обоих направлениях?
Чтобы небыло лишних записей и никто не жаловался, что его пост пропал.
Имелись в виду однотипные операции которые не выполняются паралельно.
Ну вот и объясни мне, что плохого, если какое-то время будут лишние записи. Вообще я плохо понимаю в каком смысле они лишние.... а ты?
Лишние - в смысле, их кто-то добавлял, а ссылок на них нигде не осталось.
Заботай только все про локи в доке на dev.mysql.com, особенно комментарии.
А то, что в твоем форуме этого нет - ну дык все-таки не денежные операции проводятся, вот народ и не парится.
У тебя из этих двух таблиц потом данные как-то вынимаются, правильно?
Есть такие варианты:
1) Данные вынимаются через left join. тогде можно смело без всяких блокировок делать insert сначала во вторую таблицу, потом в первую. left join не заметит "неатомарности".
2) ---||--- right join ---||--- сначала в первую таблицу, потом во вторую, ---||---
3) ---||--- inner join. Тогда вообще пофигу, пока запись не появится в обеих таблицах, её не будет в inner join-е.
4) ---||--- outer join. Ну вот я собственно в предыдущем посте и спрашивал, зачем там может понадобиться outer join?
5) Вообще без join-ов, делаются по очереди select сначала из одной таблицы, потом из другой. Тогда никакая "атомарность" insert-а тебе не поможет. Разве что лочить _обе_ таблицы перед этими двумя select-ами, а потом отпускать, но это пи**ец, а не решение, никакой нагрузки держать не будет.
Оставить комментарий
dimabel
Допустим, есть таблица (назовём её `table1` в которой одно из полей (пусть оно называется `t2_id`) должно соответствовать автоинкрементному полю (назовём его `id`) другой таблицы (`table2` либо быть равным NULL.Значение по умолчанию для `table`.`t2_id` - NULL, именно с этим значением и создаются записи в первой таблице.
Задача состоит в том, чтобы добавить во вторую таблицу запись, которая будет соответствовать записи в первой таблице. Добавление должно быть атомным, т.е., нельзя допустить, чтобы во второй таблице остались лишние записи, либо чтобы в первой таблице были битые ссылки.
Решение, которое мне пришло в голову сначала следующее (пхп-код, $id - значение автоинкрементного поля `id` для первой таблицы):
Можно-ли сделать лучше? В частности - убрать блокировки.
Дело в том, что коде форума, который я модифицирую, не нашел ни единой блокировки таблиц.