2

複数のトランザクションを持つ複数のアプリケーションによるテーブルアクセスがあり、これらの複数のアプリケーション/トランザクションが、そのトランザクションを実行するアプリケーションによって挿入された各プライマリキー/IDを取得するようにします。何らかの理由でSCOPE_IDENTITYを使用できないため、最後の並べ替えは@@IDENTITYを使用することです。トランザクション クエリでは、ブロックを回避するためにトランザクションごとにIsolationLevel.Snapshotを実装しました。

ここで私の質問は、各トランザクションが@@IDENTITYを正しく、それに応じてこのシナリオで返すかどうかです。

元。3 つのクエリを同時に実行します。

  • Transactional1 Query Insert は、予期されるリターン ID 100 を返します。
  • Transactional2 Query Insert で返される ID が 102 と予想されます。
  • Transactional3 Query Insert で返される ID が 103 と予想されます。

このようにそれに応じてアイデンティティを返しますか?これが私の目標です

  • 取引1 - 100
  • トランザクション 2 - 102
  • トランザクション3 - 103

それとも、このようなことが起こる可能性がありますか?これは私が起こることを恐れています

  • 取引1 - 102
  • トランザクション 2 - 103
  • 取引3 - 101

この既存のトリガーが、コードとクエリに SCOPE_IDENTITY があるにもかかわらず、SCOPE_IDENTITY が ID を返す理由です。

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
4

1 に答える 1

1

重要な詳細のほとんどは、次のドキュメントで説明されています。

@@IDENTITYSCOPE_IDENTITY現在のセッションの任意のテーブルで生成された最後の ID 値を返します。ただし、SCOPE_IDENTITY現在のスコープ内でのみ値を返します。@@IDENTITY特定の範囲に限定されません。

予期しない値を返す方法についての詳細もあります@@IDENTITYが、それらはすべて (予想されるように)他のセッションではなくスコープに関連しています。

他のセッションを扱っている場合に関係するこのセットの唯一の機能はIDENT_CURRENT.

もちろん、コードが(ネストされたスコープを作成する)トリガーも処理しており、ID 値を持つテーブルを操作し ( @@IDENTITY「間違った」値を返す原因となる)、SCOPE_IDENTITY何らかの理由で既に除外している場合は、対象外です。幸運。

于 2015-08-04T06:42:54.410 に答える