Зачем блокировать в Testdatabase, а не в Devdatabase

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

SQL, который создает мою проблему:

-- In one connection it runs this
set transaction isolation level read committed
begin tran
INSERT INTO [Test].[dbo].[Status] ([TransactionID], [Status]) VALUES (6122481, 1)

Затем, прежде чем эта транзакция будет зафиксирована, другое соединение попытается запустить:

set transaction isolation level read committed
begin tran
SELECT * FROM [Test].[dbo].[Status] with(rowlock) WHERE [Test].[dbo].[Status].[TransactionID] = 6122482 

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

  1. SQL Server 2008
  2. У меня нет большого контроля над фактическим SQL, мы используем для него LLBLGen (ORM)
  3. Он отлично работает с нашими базами данных разработки и производства.
  4. Тестовая база данных была создана путем восстановления новой резервной копии базы данных dev.
  5. Я думаю, что основное отличие заключается в количестве строк в таблице (‹100 в тесте по сравнению с> 100000 для dev)

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

В таблице есть несколько индексов, а также FK в таблице транзакций по TransactionID:

CREATE NONCLUSTERED INDEX [idx1] ON [dbo].[Status] 
(   [TransactionID] ASC,
    [Status] ASC
) INCLUDE ( [Created]) 

CREATE NONCLUSTERED INDEX [idx2] ON [dbo].[Status] 
(   [Status] ASC,
    [Created] ASC
) INCLUDE ( [TransactionID]) 

ALTER TABLE [dbo].[Status] ADD  CONSTRAINT [PK_Statuses] PRIMARY KEY CLUSTERED 
(   [StatusID] ASC
)

person viblo    schedule 01.10.2012    source источник
comment
Я думаю (хотя и не уверен), что SQL Server довольно ограничен, когда дело доходит до обработки блокировок строк. В какой-то момент он просто сдается и блокирует всю таблицу. Еще одним отличием может быть использование изоляции моментальных снимков в одном, но не в другом.   -  person a_horse_with_no_name    schedule 01.10.2012
comment
Есть индекс TransactionID?   -  person Martin Smith    schedule 01.10.2012
comment
Должен быть предположение отсюда. Но используйте монитор активности Sql, чтобы увидеть, какие блокировки используются. Сервер SQl будет переводить блокировки строк в блокировки страниц в рамках оптимизации, поэтому, если ваша новая вставленная строка находится на той же странице, что и та, которую вы пытаетесь выбрать. Говоря, почему ваша транзакция вставки не завершается в разумные сроки?   -  person Tony Hopkinson    schedule 01.10.2012
comment
Причина в том, что вставка не является единственной в транзакции, она сделает еще одну вставку позже, она просто ждет, среди прочего, завершения выбора.   -  person viblo    schedule 01.10.2012
comment
Монитор активности показывает, что выборка ожидает LCK_M_S.   -  person viblo    schedule 01.10.2012
comment
Сделать другую вставку позже? Как позже? Транзакции должны быть входными и выходными, зависимость от другой транзакции — не очень хорошая идея. Либо они должны быть в одной транзакции, либо вы истечете время ожидания и реализуете, что кто-то еще делает sumfin, повторите попытку позже.   -  person Tony Hopkinson    schedule 02.10.2012
comment
Он сделает это как можно скорее, ему просто нужен ответ от оператора select, прежде чем он узнает, что вставить. Я знаю, что текущий код не идеален, LLBLGen, который мы используем в качестве ORM, создает много лишнего мусора, что затрудняет отслеживание кода, а также его изменение. Тем не менее, я бы очень хотел не вносить никаких изменений в код, чтобы заставить его работать с этой пустой тестовой базой данных, когда она нормально работает как в разработке, так и в производстве.   -  person viblo    schedule 02.10.2012


Ответы (1)


Я сделал 1000 вставок в таблицу (того же INSERT, что и в вопросе) и проблема ушла. Не идеальное решение, но, по-видимому, устраняет проблему.

person viblo    schedule 02.10.2012