Как Serializable работает со вставкой в ​​SQL Server 2005 - PullRequest
1 голос
/ 09 июня 2010

G'day

Я думаю, что у меня есть неправильное понимание сериализуемого. У меня есть две таблицы (данные, транзакция), в которые я вставляю информацию в сериализуемую транзакцию (либо они оба включены, либо обе вне, но не в подвешенном состоянии).

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
INSERT INTO dbo.data (ID, data) VALUES (@Id, data)
INSERT INTO dbo.transactions(ID, info) VALUES (@ID, @info) 
COMMIT TRANSACTION

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

INSERT INTO reconciles (ReconcileID, DataID) 
SELECT Reconcile = @ReconcileID, ID FROM Data 
WHERE NOT EXISTS (SELECT 1 FROM TRANSACTIONS WHERE data.id = transactions.id)

Обратите внимание, что идентификатор на самом деле является составным (2 столбца) ключом, поэтому я не могу использовать оператор NOT IN

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

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

1 Ответ

4 голосов
/ 09 июня 2010

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

Второй запрос, INSERT ... SELECT ..., с другой стороны, содержащий чтение (SELECT), означает , на который влияет уровень изоляции. Часть SELECT будет вести себя в соответствии с текущим уровнем изоляции (в данном случае чтение зафиксировано).

Обновлено Записи в транзакции видны вне транзакции только после фиксации. Если у вас есть последовательность begin transaction; insert into A; insert into B; commit, то считыватель, который имеет не менее при изолированной фиксации чтения, не увидит вставку в A до вставки в B. Если ваш запрос на согласование видит частичную транзакцию (т.е. вставка в A без соответствующей вставки в B), тогда у вас есть несколько возможных объяснений:

  • запрос на согласование выполняется с неверным уровнем изоляции и выполняет грязное чтение
  • приложение зафиксировало две вставки отдельно
  • дефект кода в приложении, который приводит к вставке только в A

Наиболее вероятное объяснение - последнее.

...