2012-06-06 3 views
0

Я создаю веб-службу WCF для приложения Silverlight, и мне нужно иметь запись для чтения/записи при блокировке при изменении.Пессимистическая блокировка записи?

Я использую MySQL версии 5.5.11.

Чтобы быть более конкретным, я хотел бы, чтобы запрос не читал данные из строки при ее изменении.

Команды два SQL для UPDATE и SELECT, на самом деле очень просто, что-то вроде:

Update (следует заблокировать для записи/чтения):

UPDATE user SET user = ..... WHERE id = ..... 

Select (не должен быть в состоянии читать, когда заперт выше запроса):

SELECT * FROM user WHERE id = ..... 

Вот что я пытался, но это не похоже на работу или заблокировать вообще ничего:

START TRANSACTION; 
    SELECT user 
    FROM user 
    WHERE id = 'the user id' 
    FOR UPDATE; 

    UPDATE user 
    SET user = 'the user data' 
    WHERE id = 'the user id'; 
COMMIT; 
+1

Зачем даже выполнять это в транзакции? 'UPDATE' запускает атомарно все самостоятельно. Тем не менее, то, что вы пытаетесь, должно по-прежнему работать; что заставляет вас думать, что это не так? – eggyal

ответ

0

Как вы определяете, что это не блокировка записи?

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

Единственный способ, которым вы могли бы сказать, была проблема, если у вас был запрос, который запускался после начала транзакции, но возвращал исходное значение для пользователя вместо обновленного значения. Это случилось?

Я бы просто поместил это в комментарий, но он был слишком длинным, но я обновлю это с более полным ответом, основанным на вашем ответе.

+0

Привет, Должен ли SQL-запрос в моем исходном сообщении также препятствовать чтению данных из этой строки? То, что, похоже, произошло в моем случае, состоит в том, что, хотя запись была в процессе изменения, другая запись могла читать данные из нее. И/ИЛИ возвращала старое значение. Это веб-приложение, не знаю, имеет ли это значение. – SlashJ

+0

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

+0

@Armz Кроме того, я не использую mysql, поэтому я не специалист по его блокировке, но я думаю, что вы, вероятно, недопонимаете, когда вам нужно использовать FOR UPDATE. Если вы только обновляете одну таблицу, тогда строки должны быть заблокированы, и вам не нужно их блокировать самостоятельно. Проблема заключается в том, когда вам нужно, например, убедиться, что перед выпуском блокировки таблицы выполняется несколько задач. Чтобы блокировать строки между несколькими операциями обновления, вы должны использовать FOR UPDATE, чтобы они были заблокированы все время. Но для одного заявления об обновлении он лишний и лишний, я считаю. –

0

MySql использует многоуровневое управление параллелизмом by default (и это очень, очень хорошее поведение, а не MSSQL). Попробуйте использовать locking reads (LOCK IN SHARE MODE), чтобы достичь желаемого.