Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Транзакции и проблемы общего доступа...
 
 автор: Batler   (19.08.2007 в 19:00)   письмо автору
 
 

Здравствуйте. У меня есть некоторые вопросы:
1)В книге MySQL 5 в главе посвященной транзакциям написано следующее(страница 485):
Для того чтобы включить режим автоматического завершения транзакций только для отдельной последовательности операторов, можно воспользоваться оператором START TRANSACTION.
Режим автоматического завершения транзакций я так понимаю это "как только выполняется оператор обновления данных, который модифицирует таблицу, MySQL тут же сохраняет изменения на диске"(т.е. фактически каждый раз выполняет COMMIT?)

Значит оператор START TRANSACTION делает тоже самое для участка кода?
Словно если бы мы сделали вот так:
SET AUTOCOMMIT=0?

Но в официальном мануале доступном на русском языке сказано:
"Если в соединении установлено AUTOCOMMIT = 1, то пользователь, тем не менее, может использовать транзакции, начиная их с BEGIN и заканчивая при помощи COMMIT или ROLLBACK."
BEGIN я так понимаю есть синоним START TRANSACTION.
У меня вопрос, где написана верная информация? Толи START TRANSACTION начинает транзакцию и все изменения выполняются только когда дана команда COMMIT, толи наоборот, всякий раз автоматом выполняет все поступившие команды.

2)Я перепечатаю с другого форума, там где я задал вопрос:
Читая мануал по MySQL главу 7.5.8 (refman 4.0 ru) пришел к очень интересному вопросу(или заключению, смотря как рассуждать).
Представим себе следующую ситуацию: (рассматриваем с точки зрения web программирования)
Есть некоторые данные которые могут редактировать скажем как пользователь так и администратор.
Пользователь решил воспользоваться своими правами редактирования и соответственно выполнил SQL запрос (возможно сам того не желая)
к базе данных(select запрос).
Ему в форме будут доступны данные которые он правит, а потом отправляет запрос на обновление.
В это время администратор тоже подал запрос на эти же данные, но до того как пользователь успел их обновить. А запрос на изменение данных подал позже.
В результате одни данные перекроют другие.
Впринципе, ничего страшного, но появляется некоторая несогласованность...
Вопрос №1: Как ее избежать?
Ответ №1
Можно использовать транзакции, тем более что InnoDB поддерживает их + блокировку строк. Но в контексте web программирования я не слишком понимаю как это выполнить (PHP например, после завершения сценария закрывает все подключения к БД).
Ситуация описана выше. Мы открываем нашу БД.
Делаем запросы:
START TRANSACTION - начинаем транзакцию
SELECT * FROM TBL WHERE ID = '14' LOCK IN SHARE MODE; - выбираем самые свежие данные и блокируем их.
НО! Дальше данные будут выведены в форму для редактирования пользователем, значит скрипт на PHP закончит свое выполнение а => закроются все открытые соединения. Наша транзакция и блокировка на данные будут утеряны, а значит администратор опять сможет получить к ним доступ и возникнет ситуация номер 1.
4) Извесно, что чаще всего хост провайдеры ограничивают количество подключений к БД. Часто видел ситуацию когда количество подключений к БД может быть не более 1.
Что это порождает? Невозможность использование транзакций.
Представьте, если на сайт одновременно ходят большое количество человек и скажем большое количество модераторов и администраторов. Чтобы использовать транзакции модераторам и администраторам нужны выделенные подключения или я не прав.
Чесно говоря не уверен в этом. Но в мануале написано, что вложенные транзакции не допускаются, и у меня в голове возникает следующая ситуация:
Пусть количество соединений(одновременных) = 1.
Администратор выполняет некоторые запросы к БД(они связаны с операциями, которые требуют объявление транзакции).
В это время приходят два модера и тоже начинают проводить свои операции, в то время как администратор делает свои дела(используя транзакции).
Результат: даже не знаю что из этого получится =)

5)В ходе рассуждений возник еще один вопрос:
Транзакции - это последовательность операторов SQL, выполняющихся как единая операция, которая не прерывается другими клиентами. Тоесть пока происходит работа с записями таблицы, никто другой не может получить доступ к этим записям, т.к. субд МуSQL автоматически блокирует доступ к ним.
Это определение транзакции данное в книге MySQL5. Мануал по MySQL 4.0
расширяет это определение и говорит о том, что возможно использование блокировок на определенные строки и другие блокировки в рамках одной транзакции. Прав ли я, когда говорю что все блокировки, равно как и сама транзакция теряется, если скрипт заканчивает свою работу, либо явно вызвана команда о закрытии соединения с MySQL или же она будет не будет утеряня?

   
 
 автор: cheops   (20.08.2007 в 10:26)   письмо автору
 
   для: Batler   (19.08.2007 в 19:00)
 

1) Здесь не удачаная фраза - ключём является "отдельная последовательность операций" (перед этим автоматический режим рассматривается). Транзакции по умолчанию отключены, т.е. изменения на жёсткий диск сохраняются так, как если бы каждая операция была атомарна. Вы можете начать транзакцию при помощи START TRANSACTION и после выполненения любого из операторов COMMIT или ROLLBACK она завершиться и для начала следующей транзакции придётся выполнять оператор START TRANSACTION. Вы можете не писать START TRANSACTION, а перейти в режим SET AUTOCOMMIT=0 - тогда весь код будет состоять из транзакций, расположенных между COMMIT или ROLLBACK (плюс операторы приводящие к автоматическому завершению транзакций).

   
 
 автор: cheops   (20.08.2007 в 10:33)   письмо автору
 
   для: Batler   (19.08.2007 в 19:00)
 

2) Здесь пожалуй можно ввести только искусственные флаги (хранимые в специальной таблице) - которые будут блокировать доступ к информации или создавать свою собственную очередь запросов и реализовывать транзакции в рамках этой очереди.

   
 
 автор: cheops   (20.08.2007 в 10:35)   письмо автору
 
   для: Batler   (19.08.2007 в 19:00)
 

4) Имеется в виду вероятно не количество подключений (их количество в час тоже можно ограничить, но это редко делается), а количество аккаунтов? Здесь не так, вы можете иметь из под одного аккаунта массу подключений - все они будут рассматриваться как независимые - тут больше проблем привносит пункт 2).

   
 
 автор: cheops   (20.08.2007 в 10:41)   письмо автору
 
   для: Batler   (19.08.2007 в 19:00)
 

>5)В ходе рассуждений возник еще один вопрос:
>Транзакции - это последовательность операторов SQL, выполняющихся как единая операция,
>которая не прерывается другими клиентами. Тоесть пока происходит работа с записями
>таблицы, никто другой не может получить доступ к этим записям, т.к. субд МуSQL автоматически
>блокирует доступ к ним.
Нет. При транзакциях все могут писать всё что угодно, однако если встретится противоречие - будет возвращена ошибка и клиенту придётся откатываться при помощи ROLLBACK в исходную точку. Кому из двух не везёт выбирается либо временным фактором, либо случайно.

>Это определение транзакции данное в книге MySQL5. Мануал по MySQL 4.0
>расширяет это определение и говорит о том, что возможно использование блокировок на
>определенные строки и другие блокировки в рамках одной транзакции. Прав ли я, когда говорю
>что все блокировки, равно как и сама транзакция теряется, если скрипт заканчивает свою
>работу, либо явно вызвана команда о закрытии соединения с MySQL или же она будет не будет
>утеряня?
Составители документации MySQL очень любят перегружать текст техническими подробностями, которые отвлекают. На самом деле вам всё равно как проходит блокировка, так как повлиять вы на это не можете. Если скрипт заканчивает работу и разрывает соединение - транзакция завершается и все изменения записываются на диск (или не записываются).

PS Это издержки взаимодействия сессионного (MySQL) и несессионного (HTTP) протоколов.

   
 
 автор: Batler   (20.08.2007 в 16:33)   письмо автору
 
   для: cheops   (20.08.2007 в 10:41)
 

>Нет. При транзакциях все могут писать всё что угодно, однако если встретится противоречие - будет возвращена ошибка и клиенту придётся откатываться при помощи ROLLBACK в исходную точку. Кому из двух не везёт выбирается либо временным фактором, либо случайно.
Странно. Это противоречит тому определению, которое я нашел в книге...
Вобщем, для меня вопросы остаются открытыми:
Что есть транзакция и как она выполняется?
Блокировки в транзакциях. Что за зверь, принцип по которому он работает. Нужен ли он.
В мануале пишут что в транзакционной модели InnoDB есть разные типы блокировок...
Это зачем? Вы утверждаете что при транзакции все могут писать все что угодно,
но опять же в мануале указано, что если вы не хотите позволить изменять данные определенной строки то нужно блокировать ее: LOCK IN SHARE MODE...

   
 
 автор: cheops   (21.08.2007 в 11:27)   письмо автору
 
   для: Batler   (20.08.2007 в 16:33)
 

В InnoDB транзакционная модель сложнее - там действительнно вводятся изоляционных уровней. Я описывал классический вариант транзакций. Блокировки, как вы и написали, позволяют заблокировать на изменение читаемые строки - т.е. запрашиваете вы количество и пока ваша транзакция не закончится попытка изменить запрошенные из других таблиц данные будут заканчиваться неудачей.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования