2013-12-03 3 views
6

я запустить этот SQL,Почему моя полная таблица заблокирована вместо строк?

create table temp 
(
    id int, 
    name varchar(10) 
) 
insert into temp values(1,'a'); 

тогда я бегу,

select 1 from temp where id = 1 

все в порядке.

Затем я запускаю неизрасходованную вставку,

SET NOCOUNT ON; 
    DECLARE @TranCount INT; 
    SET @TranCount = @@TRANCOUNT; 



     IF @TranCount = 0 
      BEGIN TRANSACTION 
     ELSE 
      SAVE TRANSACTION Insertorupdatedevicecatalog; 

insert into temp values(2,'b') 

тогда я бег,

select 1 from temp where id = 1 

Но на этот раз ничего не возвращается. Почему мой полный стол заблокирован вместо второй строки?

+1

Тот факт, что таблица представляет собой кучу (без уникального CI, как обычно), вызывает неожиданную блокировку здесь. Эта проблема исчезнет, ​​создав уникальный идентификатор CI. – usr

+0

Я запустил код в своей локальной системе, но не смог воспроизвести его. Второй «SELECT» возвращает 1, как и ожидалось. – SchmitzIT

+0

@SchmitzIT, я тестирую это с новой базой данных, новой установкой и новой таблицей – user960567

ответ

6

SQL Server не блокирует всю таблицу. Я вижу, что один идентификатор строки заблокирован транзакцией записи.

Читатель должен сканировать всю таблицу, потому что нет индексов.

enter image description here

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

enter image description here Сессия 51 имеет вставленный идентификатор 2. Сессия 54 является заблокированной. Здесь нет блокировок страниц или таблиц (кроме блокировок, которые здесь не имеют значения).

Тот факт, что таблица представляет собой кучу (нет уникального CI, как обычно), вызывает неожиданную блокировку здесь. Эта проблема исчезнет, ​​создав уникальный идентификатор CI.

+0

Можете ли вы написать запрос, который возвращает указанные строки? – user960567

+0

Будет здорово, если вы напишете инструкции SQL, принадлежащие Session_id – user960567

+0

@ user960567 Это часть более большой коллекции скриптов. Это не изолированный запрос, он опирается на страницы и страницы других материалов. Попробуйте выбрать из sys.dm_tran_locks (http://technet.microsoft.com/en-us/library/ms190345.aspx). – usr

2

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

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

+0

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

+0

FYI, я проверил это с обновлением. Он имеет тот же результат с UPDATE. – user960567

+0

Yup, Update будет работать примерно так же, с таким количеством строк в таблице.Конечно, вставка или обновление должны занимать всего несколько MS, поэтому блокировка не будет долго жить, и пользователи даже не заметят. –

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