Что SELECT @@IDENTITY вернет, если у меня будет транзакционный запрос с IsolationLevel.Snapshot в множественном и одновременном запросе?
У меня есть доступ к таблице из нескольких приложений с несколькими транзакциями, и я хочу, чтобы эти несколько приложений / транзакций вставляли каждый первичный ключ / идентификатор соответствующим образом приложением, которое выполняет эту транзакцию. По какой-то причине я не могу использовать SCOPE_IDENTITY, поэтому моя последняя сортировка - @@IDENTITY. Для транзакционного запроса я реализовал IsolationLevel.Snapshot для каждой транзакции, чтобы избежать блокировки.
Теперь мой вопрос: будет ли каждая транзакция возвращать @@IDENTITY правильно и в соответствии с этим сценарием.
Ex. У меня три запроса выполняются одновременно:
- Transactional1 Query Insert с ожидаемым идентификатором возврата 100;
- Transactional2 Query Insert с ожидаемым идентификатором возврата 102;
- Transactional3 Query Insert с ожидаемым идентификатором возврата 103;
Будет ли он возвращать идентичность соответственно, как это? это моя цель
- Транзакция 1 - 100
- Транзакция 2 - 102
- Транзакция3 - 103
Или это может случиться так? это я боюсь случиться
- Транзакция 1 - 102
- Транзакция 2 - 103
- Транзакция3 - 101
Этот существующий триггер является причиной, по которой SCOPE_IDENTITY возвращает идентичность, даже если в моем коде и запросе есть SCOPE_IDENTITY.
ALTER trigger [dbo].[CustomerAddressesInsertVIds] on [dbo].[CustomerAddresses]
instead of insert
as
begin
set nocount on
insert into [dbo].[CustomerAddresses]
([CustomerID], [AddressTypeID], [CustomerAddressID], [AddressNameType], [Name], [ContactID], [Address1], [Address2], [Address3], [City], [County], [State], [Country], [Zip], [Phone1], [Phone2], [Fax1], [Fax2], [CreateDate], [CreateUser], [MaintenanceDate], [MaintenanceUser], [LastOrderDate], [DeleteOnDate], [SyncStatus], [SyncDate], [SyncUser], [ERPID], [CreateCustomerID], [CreateContactID], [MaintenanceCustomerID], [MaintenanceContactID], [Active], [Deleted], [LockUser], [LockSessionID], [LockDate], [InUse], [AddressTypeVId], [CustomerVId])
select
coalesce([CustomerID], (select [CustomerID] from [dbo].[Customers] where [CustomerVId]=inserted.[CustomerVId])), coalesce([AddressTypeID], (select [AddressTypeID] from [dbo].[AddressTypes] where [AddressTypeVId]=inserted.[AddressTypeVId])), [CustomerAddressID], [AddressNameType], [Name], [ContactID], [Address1], [Address2], [Address3], [City], [County], [State], [Country], [Zip], [Phone1], [Phone2], [Fax1], [Fax2], [CreateDate], [CreateUser], [MaintenanceDate], [MaintenanceUser], [LastOrderDate], [DeleteOnDate], [SyncStatus], [SyncDate], [SyncUser], [ERPID], [CreateCustomerID], [CreateContactID], [MaintenanceCustomerID], [MaintenanceContactID], [Active], [Deleted], [LockUser], [LockSessionID], [LockDate], [InUse], coalesce([AddressTypeVId], (select [AddressTypeVId] from [dbo].[AddressTypes] where [AddressTypeID]=inserted.[AddressTypeID])), coalesce([CustomerVId], (select [CustomerVId] from [dbo].[Customers] where [CustomerID]=inserted.[CustomerID]))
from inserted
end
1 ответ
Большинство важных деталей описаны в документации:
@@IDENTITY
а такжеSCOPE_IDENTITY
вернуть последнее значение идентичности, сгенерированное в любой таблице в текущем сеансе. Тем не мение,SCOPE_IDENTITY
возвращает значение только в пределах текущей области видимости;@@IDENTITY
не ограничивается конкретной областью применения.
Есть также подробности о том, как @@IDENTITY
может возвращать неожиданные значения - но все они связаны (как и следовало ожидать) с областью, а не с другими сеансами.
Единственная функция в этом наборе, которая касается, если вы имеете дело с другими сессиями, это IDENT_CURRENT
,
Конечно, если ваш код также имеет дело с триггерами (которые создают вложенные области видимости), которые также манипулируют таблицами со значениями идентичности (вызывая @@IDENTITY
вернуть "неправильное" значение), и вы уже исключили SCOPE_IDENTITY
почему-то тебе не повезло.