В чем разница между использованием индексированного столбца и неиндексированного столбца для обновления данных из разных транзакций? - PullRequest
0 голосов
/ 05 февраля 2012

У меня возникла проблема, когда я использовал транзакцию ранее.Надеюсь, кто-нибудь может помочь мне разобраться.Я буду признателен за любую помощь.Спасибо.

Структура таблицы 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 () и break (установить точку останова в затмении) в D
  2. выполнить method2 () одновременно

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

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

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

Ответы [ 2 ]

1 голос
/ 05 февраля 2012

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

Только после завершения первой транзакции вторая транзакция может продолжиться и либо:

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

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

1 голос
/ 05 февраля 2012

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...