2010-12-30 6 views
4

MySQL поддерживает ключевое слово «для обновления». Вот как я тестировал, что он работает, как ожидалось. Я открыл две вкладки браузера и выполнил следующие команды в одном окне.Mysql для обновления

mysql> start transaction; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select * from myxml where id = 2 for update; 
.... 
mysql> update myxml set id = 3 where id = 2 limit 1; 
Query OK, 1 row affected, 1 warning (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> commit; 
Query OK, 0 rows affected (0.08 sec) 

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

mysql> start transaction; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select * from myxml where id = 2 for update; 
Empty set (43.81 sec) 

Как видно из приведенного выше примера, я не мог выбрать запись на 43 секунд, так как сделка была обрабатываемый другим приложением в окне Нет 1. После того, как сделка была закончена, я должен выбрать запись, но поскольку идентификатор 2 был изменен на id 3 транзакцией, которая была выполнена первой, запись не была возвращена.

Мой вопрос в том, каковы недостатки использования синтаксиса «для обновления»? Если я не совершаю транзакцию, запущенную в окне 1, запись будет заблокирована навсегда?

+0

«недостатки», которые очень зависят от ваших требований, можете ли вы объяснить, для чего вам нужны блокировки? –

+0

Я принял ответы на почти все вопросы. Вы можете проверить это, если хотите. Пожалуйста, прекратите просить людей работать над чем-то, что невозможно :) – shantanuo

ответ

3

Да, если транзакция № 1 не зафиксирована, эти записи будут заблокированы навсегда, если только соединение не упадет, или innodb решит отменить транзакцию из-за обнаружения блокировки.

но с идентификатором 2 было изменено на 3 ID по сделке, которая была выполнена во-первых, запись не была возвращена.

Разве это не то, что вы хотите? если нет, то вы не используете SELECT ... FOR UPDATE должным образом. см. http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html

+0

Да, это то, что я хочу. Но я не хочу блокировки, если коммит не происходит по какой-либо причине, например. пользователь прервал соединение. Кроме того, есть ли способ узнать, сколько записей заблокировано для обновления в любой момент времени? – shantanuo

+1

@shantanuo Если пользователь прервал соединение, транзакция автоматически откатится. –

+0

, работая с транзакциями, вы должны справиться с тем, что у вас есть некоторые задачи ожидания. Но вы можете изменить продолжительность таймаута http://dev.mysql.com/doc/refman/5.0/en/innodb-parameters.html#sysvar_innodb_lock_wait_timeout – regilero

Смежные вопросы