IDENTITY_INSERT eşzamanlılığı nasıl etkiler?


11

Bir yayın hatası olan ve destek dışı kalan 3. taraf SAP eklentisine sahip bir müşteriye yardım etmeye çalışıyorum.

Belirli koşullar altında, kayıt kuyruğu tablosundan kayıt arşiv tablosuna kadar olan arşivleri arşivler ve tamamlanmamış gönderiler. Bu arşivlenmiş sonuçları tekrar kuyruğa taşımam gerekiyor.

Sıra kimliği bir kimlik sütunu ve aynı tutmak istiyorum.

Question_insert açık / insert / identity_insert kapalı yaparsam, kuyruk girişleri oluşturan ve kimlik sütununun otomatik olarak oluşturulmasını bekleyen süreçlerle eşzamanlılık konusunda ne bekleyebilirim?

Böyle bir davranışı sergilemenin en iyi yolunu gösteren işaretçiler de çok takdir edilecektir.

Yanıtlar:


8

IDENTITY_INSERT ONKendi başına ayarlamak eşzamanlılığı ortadan kaldırmaz - bu masaya herhangi bir özel kilit yerleştirmez, sadece kısa bir şema kararlılığı (Sch-S) kilidi.

Teorik olarak, varsayılan davranış altında ne olabilir, bunu oturum 1'de yapabilirsiniz:

BEGIN TRANSACTION;

-- 1
SET IDENTITY_INSERT dbo.tablename ON;

-- 2
INSERT dbo.tablename(id, etc) VALUES(100, 'foo'); -- next identity is now 101

-- 3
INSERT dbo.tablename(id, etc) VALUES(101, 'foo'); -- next identity is now 102

-- 4
SET IDENTITY_INSERT dbo.tablename OFF;

COMMIT TRANSACTION;

Başka bir oturumda, 1, 2, 3 veya 4. noktalarda tabloya satır ekleyebilirsiniz. Bu, iyi bir şey gibi görünebilir , ancak 2 ile 3 arasında gerçekleşen herhangi bir ek için ne olduğu dışında, otomatik olarak oluşturulan değerin tetiklenmesi başka bir oturumda ise deyim 2'nin sonuçları temel alınır - bu nedenle 101 oluşturur ve deyim 3 birincil anahtar ihlaliyle başarısız olur. Bazı WAITFORs ile kendinizi kurmak ve test etmek oldukça basittir :

-- session 1
-- DROP TABLE dbo.what;
CREATE TABLE dbo.what(id INT IDENTITY PRIMARY KEY);
GO
BEGIN TRANSACTION;

SET IDENTITY_INSERT dbo.what ON;

INSERT dbo.what(id) VALUES(32);
WAITFOR DELAY '00:00:05';
INSERT dbo.what(id) VALUES(33);
WAITFOR DELAY '00:00:05';
INSERT dbo.what(id) VALUES(34);
WAITFOR DELAY '00:00:05';
INSERT dbo.what(id) VALUES(35);
WAITFOR DELAY '00:00:05';
INSERT dbo.what(id) VALUES(36);

SET IDENTITY_INSERT dbo.what OFF;

COMMIT TRANSACTION;

Bu toplu işlem başladığında, bu toplu işi başka bir pencerede başlatın:

-- session 2
INSERT dbo.what DEFAULT VALUES;
WAITFOR DELAY '00:00:01';
GO 20

2. Oturum, yalnızca 1-20 arasındaki değerleri eklemelidir, değil mi? Bunun dışında, temel kimlik el ile eklenen oturum 1'iniz tarafından güncellendiğinden, bir noktada oturum 2'nin oturum 1'in kaldığı yerden devam edeceği ve 32, 33 veya 34 vb. Ekleneceği kabul edilir, ancak bunun yapılmasına izin verilir, ancak daha sonra oturum 1, PK ihlali ile bir sonraki ekte başarısız olur (ki bu kazanma yalnızca bir zamanlama meselesi olabilir).

Bunu geçici olarak çözmenin bir yolu TABLOCK, ilk ekte a çağırmaktır :

INSERT dbo.what WITH (TABLOCK) (id) VALUES(32);

Bu, arşivlenen satırları geri taşıyana kadar bu tabloyu eklemeye (veya gerçekten bir şey yapmaya) çalışan diğer kullanıcıları engeller. Bu eşzamanlılığı daraltıyor, elbette, ancak engellemenin çalışmasını istediğiniz yol budur . Ve umarım bu, diğer insanları her zaman engellediğiniz kadar sık ​​görülen bir şey değildir.

Diğer birkaç geçici çözüm:

  • IDENTITYüretilen değerin bakımını durdurun . Kimin umrunda? Bir kullanma UNIQUEIDENTIFIER(belki ile ayrı bir tabloda oluşturulan IDENTITYorijinal değeri çok önemli ise bir yedek olarak).
  • başlangıçta arşivlenmiş olarak işaretlenen ve arşivin daha sonraki bir tarihe kadar kalıcı olmadığı bir "yumuşak silme" kullanmak için arşivleme işlemini değiştirin. Daha sonra, onları geri almaya çalışan her işlem doğrudan bir güncelleme yapabilir ve yumuşak silme bayrağını düzeltebilir.

Açıklamanız için teşekkürler. Bu kimlik alanlarını oluşturan destek dışı bir ürüne yardımcı olmak için tek başına bir yardımcı program yazıyorum. Nasıl çalıştığı üzerinde hiçbir kontrolüm yok.
Metafor
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.