2012-02-05 2 views
0

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

MySql структура таблицы:

create table test (
    id int not null, 
    someid int, 
    name varchar(50), 
    update_date datetime 
); 
primary key : id (auto-inc) 
index1 : id (unique) 
index2 : id, update_date (non-unique) 

метод Java:

// consider this method is Transaction 1 
method1() { 
    A. set session transaction isolation level read commited; 
    B. select update_date from test where someid = 1; 
    C. insert into test values (some new data..); 
    D. select update_date from test where someid = 1; 
} 

// consider this method is Transaction 2 
methodb() { 
    E. (start with default transaction isolation level - repeatable read) 
    F. update test set udpate_date = now() where someid = 1; 
} 

Вот что я сделал:

  1. выполнить method1() и перерыв (точка множества разрыва в затмении) при D
  2. выполнить метод2() одновременно

Обратите внимание, что «someid» не находится в индексе, но он сохраняет те же данные, что и «id».

Тогда у меня ничего нет, кроме как ждать, пока я не совершаю транзакцию1 или, в конце концов, это закончится таймаутом транзакции. Но если бы я изменил where clause на id = 1 F, он будет работать нормально, без каких-либо остановок. Здесь я запутался, потому что я не блокировал эту таблицу или любые строки. И если я это сделал, это не должно быть сделано, правильно?

Может ли кто-нибудь сказать мне, почему это произошло? Спасибо!

ответ

1

Условие someId = 1 требует, чтобы система базы данных просматривала полную таблицу, потому что нет индекса. Оператор insert может вставить строку с someid = 1 и, следовательно, повлиять на результат второй транзакции.

В случае, когда id = 1, dbs может определить, что статусом F является только одна строка. Статут вставки не меняет эту строку.

Мне просто интересно, влияет ли уровень изоляции на выполнение?

+0

Благодарим вас за ответ! Имеет смысл, как обновление происходит, по крайней мере, я так думаю. Ну, я не знаком с транзакциями, но немного сложно верить, что уровень изоляции влияет на статус обновления, для меня по крайней мере :-) – redfoxlee

+0

Кстати: похоже, уровень изоляции влияет на режим блокировки. Но в этом случае я не вижу различий между READ COMMITED и REPEATABLE READ. – redfoxlee

1

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

только после того, как первая сделка заканчивает может вторая транзакция продолжится и либо:

  • обновление строки (если первая сделка совершено)
  • или нет обновления строки (если первый откат транзакции, поэтому строка фактически не вставлена).

Вопрос: почему это не произошло с индексированным id? Вы уверены, что использовали одну и ту же стоимость для обеих транзакций, как и для someid? Вы изменили предложение WHERE для обеих транзакций?

+0

Благодарим вас за ответ, во-первых. Моя цель - скопировать некоторые данные из «теста» в качестве шаблона и вставить их обратно в ту же таблицу. Поэтому я должен убедиться, что у меня есть правильная копия, поэтому я использовал метод выше. И да, я уверен, что использовал ту же ценность для обеих транзакций. Ну, я не знаю, на данный момент кажется, что ответ tkr имеет смысл здесь :-). Любые другие идеи? – redfoxlee

+0

@redfoxlee Тот факт, что вторая транзакция разблокирует _exactly_, когда первая совершена, является сильным признаком наличия какой-либо блокировки. Какой механизм хранения вы используете? Я нашел интересную цитату для механизма [MyISAM] (http://dev.mysql.com/doc/refman/5.6/en/internal-locking.html): «Если есть дыры, одновременные вставки отключены, но включены снова автоматически, когда все отверстия заполнены новыми данными. "_. Может быть, вам просто не повезло попасть в эти отверстия? Описанное вами поведение происходит последовательно - вы неоднократно проверяли? –

+0

Ну, я не повезло некоторое время с тех пор, как я начал ... Но я уверен, что мне повезло с этим, потому что я использую движок InnoDB :-). И да, я сделал этот тест несколько раз, и это происходит каждый раз :-( – redfoxlee

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

  • Нет связанных вопросов^_^