যদি টেবিল ভেরিয়েবল কেবল কখনও একটি মান ধরে রাখে তবে সমস্যা হবে না। একাধিক সারি সহ, অচলাবস্থার জন্য নতুন সম্ভাবনা রয়েছে। ধরা যাক একই সংস্থার জন্য দুটি কন্ট্রন্ট প্রসেস (এন্ড বি) টেবিল ভেরিয়েবল (1, 2) এবং (2, 1) সমেত চলমান।
প্রক্রিয়া এ গন্তব্যটি পড়ে, কোনও সারি খুঁজে পায় না এবং '1 'মান সন্নিবেশ করে। এটিতে '1' মানের উপর একচেটিয়া সারি লক রয়েছে। প্রক্রিয়া বি গন্তব্যটি পড়ে, কোনও সারি খুঁজে পায় না এবং '2' মান সন্নিবেশ করে। এটি '2' মানের উপর একচেটিয়া সারি লক ধারণ করে।
এখন প্রক্রিয়া A কে সারি 2 প্রক্রিয়াজাতকরণ করা দরকার, এবং প্রসেস বি এর সারি 1 টি প্রক্রিয়া করা দরকার ither কোনও প্রক্রিয়াই অগ্রগতি করতে পারে না কারণ এটির জন্য একটি লক প্রয়োজন যা অন্য প্রক্রিয়াটির সাথে রাখা একচেটিয়া লকের সাথে সামঞ্জস্য নয়।
একাধিক সারি সহ ডেডলকগুলি এড়াতে, প্রতি বার একই ক্রমে সারিগুলি প্রক্রিয়া করা প্রয়োজন (এবং সারণী অ্যাক্সেস করা) । প্রশ্নটিতে প্রদর্শিত সম্পাদন পরিকল্পনার টেবিল পরিবর্তনশীলটি একটি গাদা, সুতরাং সারিগুলির কোনও অভ্যন্তরীণ ক্রম নেই (এগুলি সুনির্দিষ্ট না হলেও সন্নিবেশ ক্রমে পড়ার সম্ভাবনা রয়েছে):
ধারাবাহিক সারি প্রক্রিয়াকরণ আদেশের অভাব সরাসরি অচল সুযোগের দিকে নিয়ে যায়। দ্বিতীয় বিবেচনাটি হ'ল কোনও মূল স্বাতন্ত্র্য গ্যারান্টির অভাবের অর্থ হ'ল হ্যালোইন সুরক্ষা সরবরাহ করার জন্য একটি টেবিল স্পুল প্রয়োজনীয়। স্পুলটি একটি উত্সাহী স্পুল, যার অর্থ সমস্ত সারি একটি টেম্পডবি ওয়ার্কটেবেলে লেখা হয় আবার পড়ার আগে এবং সন্নিবেশ অপারেটরের জন্য পুনরায় খেলতে হবে ।
TYPE
একটি ক্লাস্টার অন্তর্ভুক্ত করতে সারণীর ভেরিয়েবলের পুনরায় সংজ্ঞা দেওয়া PRIMARY KEY
:
DROP TYPE dbo.CoUserData;
CREATE TYPE dbo.CoUserData
AS TABLE
(
MyKey integer NOT NULL PRIMARY KEY CLUSTERED,
MyValue integer NOT NULL
);
এক্সিকিউশন প্ল্যানটি এখন ক্লাস্টারড ইনডেক্সের একটি স্ক্যান দেখায় এবং স্বাতন্ত্র্য গ্যারান্টি মানে অপ্টিমাইজার নিরাপদে টেবিল স্পুলটি সরিয়ে ফেলতে সক্ষম:
MERGE
128 থ্রেডে স্টেটমেন্টের 5000 টি পুনরাবৃত্তি সহ পরীক্ষায় , ক্লাস্টার টেবিল ভেরিয়েবলের সাথে কোনও অচলাবস্থা ঘটেনি। আমার জোর দেওয়া উচিত যে এটি কেবল পর্যবেক্ষণের ভিত্তিতেই; ক্লাস্টার্ড টেবিল ভেরিয়েবলটি ( প্রযুক্তিগতভাবে ) বিভিন্ন ক্রমে তার সারিগুলি তৈরি করতে পারে , তবে একটি ধারাবাহিক ক্রমের সম্ভাবনা খুব বড় করে বর্ধিত হয়। পর্যবেক্ষণ করা আচরণ অবশ্যই প্রতিটি নতুন ক্রম আপডেট, পরিষেবা প্যাক, বা এসকিউএল সার্ভারের নতুন সংস্করণে অবশ্যই পরীক্ষা করা প্রয়োজন।
সারণির ভেরিয়েবল সংজ্ঞা পরিবর্তন করা যায় না, এর জন্য আরও একটি বিকল্প রয়েছে:
MERGE dbo.CompanyUser AS R
USING
(SELECT DISTINCT MyKey, MyValue FROM @DataTable) AS NewData ON
R.CompanyId = @CompanyID
AND R.UserID = @UserID
AND R.MyKey = NewData.MyKey
WHEN NOT MATCHED THEN
INSERT
(CompanyID, UserID, MyKey, MyValue)
VALUES
(@CompanyID, @UserID, NewData.MyKey, NewData.MyValue)
OPTION (ORDER GROUP);
এটি একটি স্পষ্ট ধরণের প্রবর্তনের ব্যয়ে স্পুল (এবং সারি-ক্রমের ধারাবাহিকতা) নির্মূলকরণও অর্জন করে:
এই পরিকল্পনাটি একই পরীক্ষা ব্যবহার করে কোনও অচলাবস্থা তৈরি করে নি। নীচে প্রজনন স্ক্রিপ্ট:
CREATE TYPE dbo.CoUserData
AS TABLE
(
MyKey integer NOT NULL /* PRIMARY KEY */,
MyValue integer NOT NULL
);
GO
CREATE TABLE dbo.Company
(
CompanyID integer NOT NULL
CONSTRAINT PK_Company
PRIMARY KEY (CompanyID)
);
GO
CREATE TABLE dbo.CompanyUser
(
CompanyID integer NOT NULL,
UserID integer NOT NULL,
MyKey integer NOT NULL,
MyValue integer NOT NULL
CONSTRAINT PK_CompanyUser
PRIMARY KEY CLUSTERED
(CompanyID, UserID, MyKey),
FOREIGN KEY (CompanyID)
REFERENCES dbo.Company (CompanyID),
);
GO
CREATE NONCLUSTERED INDEX nc1
ON dbo.CompanyUser (CompanyID, UserID);
GO
INSERT dbo.Company (CompanyID) VALUES (1);
GO
DECLARE
@DataTable AS dbo.CoUserData,
@CompanyID integer = 1,
@UserID integer = 1;
INSERT @DataTable
SELECT TOP (10)
V.MyKey,
V.MyValue
FROM
(
VALUES
(1, 1),
(2, 2),
(3, 3),
(4, 4),
(5, 5),
(6, 6),
(7, 7),
(8, 8),
(9, 9)
) AS V (MyKey, MyValue)
ORDER BY NEWID();
BEGIN TRANSACTION;
-- Test MERGE statement here
ROLLBACK TRANSACTION;