|
|
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
Здравствуйте! Очень навязчивый вопрос, который не даёт мне покоя! Есть автомобильный сайт. Пользователи вбивают свои объявы о продаже. Затронуты следующие таблицы: // Запись в общую для всех таблицу 1. INSERT INTO `таблица_авто_общая` $my_id = mysql_insert_id(); // Запись в таблицу типа транспортного средства (легковой, грузовой, спецтехника) 2. INSERT INTO `таблица_типа_авто` WHERE id=$my_id // Запись в таблицу комплектаций (ABS, Магнитола, Люк, Электрозеркала) 3. INSERT INTO `таблица_комплектаций_авто` WHERE id=$my_id // Загружаем фото тачки в файловую систему 4. uppload_auto_images($my_id); // Названия загруженных фоток вставляем в 5. INSERT INTO `таблица_фотографий_авто` WHERE id=$my_id Итого - запись идёт в 4 таблицы + загрузка фоток на сервер (php-функция) Всё работает, но боюсь что если одновременно куча народу с разных компов будет объявление своё подавать - всё может перепутаться к чёрту! Да и постоянно xml-файлы с кучей объявлений будут приходить, которые специальный скрипт постоянно парсит и подобным образом запихивает тачки в базу. Или mysql сама берёт на себя задачи по блокировки и ни чей чужой поток не вклинится? Транзакции я использовать не могу тк у меня не используется php-класс PDO. Остаются только блокировки на запись. Вот и думаю - может в моём случае не нужны и даже блокировки? Мускул сам следит? Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2014, 13:03:05 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
iova1984Транзакции я использовать не могу тк у меня не используется php-класс PDO.Расширение mysqli умеет работать с транзакциями - чтобы это выяснить, достаточно поискать "php mysqli transaction". iova1984Вот и думаю - может в моём случае не нужны и даже блокировки? Мускул сам следит?Вы показали несколько огрызков скл-запросов и вызов одной пхп-функции, и хотите, чтобы вам на основании этих данных дали ответ? Навряд ли среди форумчан найдётся хоть один человек с прокачанной до такого уровня телепатией :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2014, 13:15:22 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
tangliriova1984Транзакции я использовать не могу тк у меня не используется php-класс PDO.Расширение mysqli умеет работать с транзакциями - чтобы это выяснить, достаточно поискать "php mysqli transaction". iova1984Вот и думаю - может в моём случае не нужны и даже блокировки? Мускул сам следит?Вы показали несколько огрызков скл-запросов и вызов одной пхп-функции, и хотите, чтобы вам на основании этих данных дали ответ? Навряд ли среди форумчан найдётся хоть один человек с прокачанной до такого уровня телепатией :) Я привёл в упрощённом виде. Реально у меня так: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. Так что тут при всём желании транзакции не сделаешь - ведь запросы идут не сплошняком, а между ними есть php-условия IF/ELSE, да и php-функции типа uppload_auto_images(); И я даже не о транзакциях, я про то, - не спутаются ли записи если куча народу будет свои тачки вбивать..... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2014, 13:21:43 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
iova1984Так что тут при всём желании транзакции не сделаешь - ведь запросы идут не сплошнякомТранзакции к "запросы идут не сплошняком" не имеют никакого отношения. И даже у случае использования mysql не вижу почему нельзя сделать mysql_query('START TRANSACTION') а потом mysql_query('COMMIT'). iova1984не спутаются ли записи если куча народу будет свои тачки вбиватьСамо слово "спутаются" тут не применимо. В записи записывается ровно то, что вы туда запишете. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2014, 13:32:14 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
iova1984я про то, - не спутаются ли записи если куча народу будет свои тачки вбиватьlast_insert_id() выводит ид последней добавленной записи в рамках сессии не спутаются ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2014, 13:51:44 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
tangliriova1984я про то, - не спутаются ли записи если куча народу будет свои тачки вбиватьlast_insert_id() выводит ид последней добавленной записи в рамках сессии не спутаются ага, с этим тогда всё ясно - с "LOCK TABLES" на WRITE- нет смысла загоняться. Единственное как я понял, где можеть быть "засада" - это то, что при сбое сервера часть INSERT-во может не выполниться. Соответственно, копать нужно именно в сторону транзакций. Я прав? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2014, 13:58:42 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
iova1984tanglirпропущено... last_insert_id() выводит ид последней добавленной записи в рамках сессии не спутаются ага, с этим тогда всё ясно - с "LOCK TABLES" на WRITE- нет смысла загоняться. Единственное как я понял, где можеть быть "засада" - это то, что при сбое сервера часть INSERT-во может не выполниться. Соответственно, копать нужно именно в сторону транзакций. Я прав? а там и копать нечего... Код: php 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. "; [/SRC] правдай есть такие драйвера что не позволяют за один заход много запросов послать...но опять же...это всё в рамках одной сесии, тогда тоже самое что и выше только Код: php 1. 2. 3. 4. 5. 6. 7. 8. 9. и в цикле выполнить по одной команде ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2014, 16:37:53 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
alex564657498765453iova1984пропущено... ага, с этим тогда всё ясно - с "LOCK TABLES" на WRITE- нет смысла загоняться. Единственное как я понял, где можеть быть "засада" - это то, что при сбое сервера часть INSERT-во может не выполниться. Соответственно, копать нужно именно в сторону транзакций. Я прав? а там и копать нечего... Код: php 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. "; [/SRC] правдай есть такие драйвера что не позволяют за один заход много запросов послать...но опять же...это всё в рамках одной сесии, тогда тоже самое что и выше только Код: php 1. 2. 3. 4. 5. 6. 7. 8. 9. и в цикле выполнить по одной команде Ух ты - спасибо, а то я думал что без PDO транзакции не сделать. Ладно бы ИНСЕРТЫ друг-за-другом шли, но меня смущали php-вставки между ИНСЕРТАМИ типа if/elseif и php-функции загрузки фоток на сервер. А ваш вариант меня заинтересовал! Я использую mysqldb_class.php. Там связь с базой идёт так: $db = new db_MySQL; $db->Connect(); и тд. Соответственно я не могу за 1 ход много запросов послать - не поддерживает данный класс такого. Буду пробовать и тестировать ваш 2-й вариант, спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2014, 17:02:48 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
И кстати, про транзакции, никак не пойму: После START TRANSACTION - идёт набор запросов (INSERTов в моём случае). А в конце - либо COMMIT (внести изменение), или ROLLBACK (отменить, откатить). И вот: Явно указать мне COMMIT - если в каком-то из INSERT-ов ошибка - мускул сам его заменит на ROLLBACK? Или же каждый из INSERT-ов самому проверять на наличие ошибки - если попалась ошибка - писать в конце ROLLBACK, если всё норм - COMMIT? Или mysql сам следит за этим и сам знает, что подразумевать в конце - commit или rollback? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2014, 17:11:31 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
вот это всё хорошо будет работать в хранимой процедуре Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2014, 17:18:54 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
автор? Или mysql сам следит за этим и сам знает, что подразумевать в конце - commit или rollback? не следит, писать самому. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2014, 17:23:44 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
Транзакции работают! Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Тут всё отлично. Единственное, что мне осталось - это перед ИНСЕРТ-ом в `CAR` (после query[3]) - вывести на php LAST_INSERT_ID, который мы в query[3] записали в @a. Типа, должно получиться что-то вроде: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. То есть, сразу после успешного получений last_id для мускула и переде вставкой в CAR - мне нужно на php вывести этот самый last_id (@a). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2014, 09:59:55 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
Аа, всё, проблема решена так: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Отдельное спасибо alex564657498765453 за 2-й вариант! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2014, 10:38:18 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
iova1984 Код: sql 1. 2. Выключать автокоммит нет смысла, если вы явно начинаете транзакцию. А если его таки выключать, то имеет смысл выключить его один раз в начале скрипта, а потом не начинать каждую транзакцию отдельно, а только их коммитить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2014, 13:24:15 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
Кстати, зачем пихать управление транзакциями в массив - не понятно. Почему сразу не вызвать эти команды? роллбэк после них все равно не нужен, даже если они выполнятся с ошибкой. И проверять успешность по AffectedRows() как-то странно, обычно функции Query возвращают false в случае неудачи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2014, 13:27:56 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
miksoftiova1984 Код: sql 1. 2. Выключать автокоммит нет смысла, если вы явно начинаете транзакцию. А если его таки выключать, то имеет смысл выключить его один раз в начале скрипта, а потом не начинать каждую транзакцию отдельно, а только их коммитить. Ну у меня же куча файлов и фуннкций, который связаны между собой... А транзакция мне нужна лишь в 2 случаях - добавлении тачки и удалении тачки. Только эти в функции должна оперировать сразу с несколькими таблицами одним махом. Остальные 99% кода транзакции не используют, посему нет смысла объявлять начало транзакции глобально. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2014, 13:28:30 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
iova1984miksoftпропущено... Выключать автокоммит нет смысла, если вы явно начинаете транзакцию. А если его таки выключать, то имеет смысл выключить его один раз в начале скрипта, а потом не начинать каждую транзакцию отдельно, а только их коммитить. Ну у меня же куча файлов и фуннкций, который связаны между собой... А транзакция мне нужна лишь в 2 случаях - добавлении тачки и удалении тачки. Только эти в функции должна оперировать сразу с несколькими таблицами одним махом. Остальные 99% кода транзакции не используют, посему нет смысла объявлять начало транзакции глобально.Так ваше set local autocommit=0 этому противоречит. В этой команде автокоммит выключается до конца работы MySQL-сессии или до явного включения обратно. Т.е. любой update/insert/delete после этого блока кода неявно начнет транзакцию, но кто ее закончит? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2014, 13:31:15 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
miksoftКстати, зачем пихать управление транзакциями в массив - не понятно. Почему сразу не вызвать эти команды? роллбэк после них все равно не нужен, даже если они выполнятся с ошибкой. И проверять успешность по AffectedRows() как-то странно, обычно функции Query возвращают false в случае неудачи. 1. Это верно - переделаю - в массиве будут лишь INSERT-ы (в моём псевдокоде - 2 инсерта - в `auto` и `car`). 2. Как так rollback не нужен? Надо же указать мускулу что если ошибка - делать откат. Иначе от сам COMMIT поставит и заинсертит лишь в 1 табличку. Я проверял. 3. А как мне проверять успешность выполнения каждого ИНСЕРТ-а?? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2014, 13:33:01 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
iova19842. Как так rollback не нужен? Надо же указать мускулу что если ошибка - делать откат. Иначе от сам COMMIT поставит и заинсертит лишь в 1 табличку. Я проверял.я говорил про команды управления транзакциями, это не инсерт. iova19843. А как мне проверять успешность выполнения каждого ИНСЕРТ-а??miksoftобычно функции Query возвращают false в случае неудачи.Дополнение - проверьте в доке по используемой функции $db->Query(). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2014, 13:36:34 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
iova1984А как мне проверять успешность выполнения каждого ИНСЕРТ-а?? miksoftобычно функции Query возвращают false в случае неудачи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2014, 13:36:59 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
miksoftТак ваше set local autocommit=0 этому противоречит. В этой команде автокоммит выключается до конца работы MySQL-сессии или до явного включения обратно. Т.е. любой update/insert/delete после этого блока кода неявно начнет транзакцию, но кто ее закончит? Ксати да, спасибо, обралил внимание. Как я понял, тогда уже если я явно указал "set local autocommit=0" - то после commit/rollback - следует написать "set local autocommit=1", ага? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2014, 15:10:20 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
iova1984miksoftТак ваше set local autocommit=0 этому противоречит. В этой команде автокоммит выключается до конца работы MySQL-сессии или до явного включения обратно. Т.е. любой update/insert/delete после этого блока кода неявно начнет транзакцию, но кто ее закончит? Ксати да, спасибо, обралил внимание. Как я понял, тогда уже если я явно указал "set local autocommit=0" - то после commit/rollback - следует написать "set local autocommit=1", ага?Да нет же! miksoftВыключать автокоммит нет смысла, если вы явно начинаете транзакцию. А если его таки выключать, то имеет смысл выключить его один раз в начале скрипта, а потом не начинать каждую транзакцию отдельно, а только их коммитить.Т.е. что-то одно - или выключаете автокоммит, или явно начинаете транзакции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2014, 15:12:28 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
Вот мой окончательный псевдокод! set autocommit вообще нигде не писал: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2014, 16:07:11 |
|
||
|
INSERT в несколько таблиц и блокировки/транзакции
|
|||
|---|---|---|---|
|
#18+
С точки зрения MySQL - вроде правильно. С точки зрения PHP - кошмар. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2014, 16:09:25 |
|
||
|
|

start [/forum/topic.php?fid=47&msg=38721406&tid=1834359]: |
0ms |
get settings: |
5ms |
get forum list: |
14ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
39ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
65ms |
get tp. blocked users: |
1ms |
| others: | 205ms |
| total: | 343ms |

| 0 / 0 |
