запутался в транзакциях mysql в php - PullRequest
3 голосов
/ 14 ноября 2011

если я использую транзакции, заблокирует ли она таблицы и не позволит ли она другим пользователям вносить какие-либо изменения?

псевдокод:

 begin transaction
   issue a select query
   issue a update query
 end transaction

так, между этими двумя запросамивозможно ли внести какие-либо изменения с помощью другого оператора обновления или чего-то, что было сделано с другой страницы?

или с момента начала транзакции будут заблокированы используемые таблицы?

Что такоеразница между транзакцией и таблицей блокировок?будет ли транзакция неявно блокировать таблицу?

Редактировать: Это то, что я хочу сделать:

{
    // Check Table2 (posted messages)
    // If is_approved is FALSE for a given msg_id
    {
        // Set is_approved to TRUE
        // Update Table1 (member details) post_count_month++
        //     and post_count_lifetime++
    }
    // Else
    {
        // NOOP
    }
}

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

Это две ситуации, с которыми я сталкиваюсь.

Ответы [ 3 ]

2 голосов
/ 14 ноября 2011

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

Посмотрите на оператор SELECT ... FOR UPDATE .

Обновление № 1:

Хорошо, вот код:

START TRANSACTION;

SELECT member_id, is_approved
FROM posted_messages
WHERE msg_id=31416
FOR UPDATE;

UPDATE member_details
SET post_count_month=post_count_month+1, post_count_lifetime=post_count_lifetime+1
WHERE member_id=123;

UPDATE posted_messages
SET is_approved=TRUE
WHERE msg_id=31416;

COMMIT;

(Я не уверен, насколько это будет полезно, учитывая, что я изобрел все запросы. Понимание кода всегда лучше, чем копирование и вставка.)

Обновление № 2:

Я отредактировал пример кода, чтобы окружить запросы в транзакции. Я сказал, что транзакции и блокировка таблиц - это разные функции, и это все еще верно. Однако SELECT ... FOR UPDATE работает внутри транзакции. Это просто деталь реализации.

Блокировка строк для обновления с помощью SELECT FOR UPDATE применяется только тогда, когда автокоммит отключен (либо путем начала транзакции с помощью START TRANSACTION или установив autocommit на 0. Если autocommit включен, строки, соответствующие спецификации, не блокируются.

1 голос
/ 14 ноября 2011

Транзакции предназначены для того, чтобы сделать операции с базой данных атомарными (или неделимыми).

Представьте себе проблему, которая у вас возникнет, если вы делаете приращение.

Сначала вы читаете значение как 1, затем добавляете 1 к нему, чтобы стать 2, а затем записываете 2 обратно в базу данных.

Если в момент между добавлением 1 и обратной записью в базу данных кто-то другой сделает то же самое и прочитает значение 1, возможно, вычтет 1, а затем запишет как 0. Одно из значений будет потеряно. Конечный результат будет равен 2 или 0 в зависимости от порядка применения обновлений.

(подробнее см. http://en.wikipedia.org/wiki/Race_condition)

Что касается блокировки таблиц во время транзакций, то это будет зависеть от используемой системы управления базами данных.

Для некоторых это не будет блокировать таблицы, но вызовет исключение, когда обновления вызовут несоответствия с результатом. Форсирование так называемого «автоматического отката».

Для других dbms они могут реализовать это с помощью блокировок.

0 голосов
/ 17 ноября 2011

Прежде всего, это зависит от механизма хранения, который вы используете для своих таблиц.Все разные странные вещи могут происходить с различными настройками mysql / опциями подсистемы хранилища.

Если, например, у вас есть таблицы InnoDB и разрешено грязное чтение - это означает, что другой клиент может читать строки-призраки - которые не существуют - разные и т. Д.

...