যেহেতু আপনি একটি সিকোয়েন্স ব্যবহার করছেন, আপনি ফাংশনের জন্য একই নেক্সট ভ্যালুটি ব্যবহার করতে পারেন - যেটি আপনার আগে থেকেই Id
প্রাথমিক কী ক্ষেত্রে একটি ডিফল্ট সীমাবদ্ধতায় রয়েছে - Id
সময়ের আগে একটি নতুন মান উত্পন্ন করতে । প্রথমে মান উত্পন্ন করার অর্থ হ'ল আপনাকে না থাকার বিষয়ে চিন্তা করার দরকার নেই SCOPE_IDENTITY
, যার অর্থ হল নতুন মান পাওয়ার জন্য আপনাকে আর OUTPUT
ধারা বা প্রয়োজনের অতিরিক্ত SELECT
দরকার নেই; আপনি এটি করার আগে আপনার মূল্য হবে INSERT
এবং আপনাকে এমনকি SET IDENTITY INSERT ON / OFF
:-) নিয়ে গণ্ডগোলের দরকার নেই
সুতরাং এটি সামগ্রিক পরিস্থিতির একটি অংশের যত্ন নেয়। অন্য অংশটি হ'ল দুটি প্রক্রিয়াটির সামঞ্জস্য ইস্যুটি হুবহু একই সময়ে, সঠিক একই স্ট্রিংয়ের জন্য বিদ্যমান সারিটি খুঁজে না পাওয়া এবং এর সাথে এগিয়ে চলছে INSERT
। উদ্বেগটি হ'ল ইউনিক সীমাবদ্ধতা লঙ্ঘন এড়ানো সম্পর্কে।
এই ধরণের সম্মতি সংক্রান্ত সমস্যাগুলি হ্যান্ডেল করার একটি উপায় হল এই নির্দিষ্ট ক্রিয়াকে একক থ্রেড করাতে বাধ্য করা। এটি করার উপায় হ'ল অ্যাপ্লিকেশন লকগুলি (যা অধিবেশন জুড়ে কাজ করে) ব্যবহার করে। কার্যকর থাকাকালীন, তারা এ জাতীয় পরিস্থিতির জন্য কিছুটা ভারী হাতের হতে পারে যেখানে সংঘর্ষের ফ্রিকোয়েন্সি সম্ভবত মোটামুটি কম।
সংঘর্ষগুলির সাথে মোকাবিলা করার অন্য উপায়টি হ'ল এটিকে এড়াতে চেষ্টা করার চেয়ে তারা কখনও কখনও ঘটবে এবং তাদের পরিচালনা করবে তা গ্রহণ করা। TRY...CATCH
কনস্ট্রাক্টটি ব্যবহার করে আপনি কার্যকরভাবে একটি নির্দিষ্ট ত্রুটি আটকে রাখতে পারেন (এই ক্ষেত্রে: "অনন্য প্রতিবন্ধকতা লঙ্ঘন", এমএসজি ২0০১) এবং মানটি SELECT
পেতে পুনরায় সম্পাদন করতে পারেন Id
যেহেতু আমরা জানি যে এটি বর্তমানে CATCH
সেই নির্দিষ্ট সাথে ব্লকের মধ্যে থাকার কারণে রয়েছে know ত্রুটি. অন্যান্য ত্রুটিগুলি সাধারণত RAISERROR
/ RETURN
বা THROW
পদ্ধতিতে পরিচালনা করা যায়।
পরীক্ষার সেটআপ: সিকোয়েন্স, সারণী এবং অনন্য সূচি
USE [tempdb];
CREATE SEQUENCE dbo.MagicNumber
AS INT
START WITH 1
INCREMENT BY 1;
CREATE TABLE dbo.NameLookup
(
[Id] INT NOT NULL
CONSTRAINT [PK_NameLookup] PRIMARY KEY CLUSTERED
CONSTRAINT [DF_NameLookup_Id] DEFAULT (NEXT VALUE FOR dbo.MagicNumber),
[ItemName] NVARCHAR(50) NOT NULL
);
CREATE UNIQUE NONCLUSTERED INDEX [UIX_NameLookup_ItemName]
ON dbo.NameLookup ([ItemName]);
GO
পরীক্ষা সেটআপ: সঞ্চিত পদ্ধতি
CREATE PROCEDURE dbo.GetOrInsertName
(
@SomeName NVARCHAR(50),
@ID INT OUTPUT,
@TestRaceCondition BIT = 0
)
AS
SET NOCOUNT ON;
BEGIN TRY
SELECT @ID = nl.[Id]
FROM dbo.NameLookup nl
WHERE nl.[ItemName] = @SomeName
AND @TestRaceCondition = 0;
IF (@ID IS NULL)
BEGIN
SET @ID = NEXT VALUE FOR dbo.MagicNumber;
INSERT INTO dbo.NameLookup ([Id], [ItemName])
VALUES (@ID, @SomeName);
END;
END TRY
BEGIN CATCH
IF (ERROR_NUMBER() = 2601) -- "Cannot insert duplicate key row in object"
BEGIN
SELECT @ID = nl.[Id]
FROM dbo.NameLookup nl
WHERE nl.[ItemName] = @SomeName;
END;
ELSE
BEGIN
;THROW; -- SQL Server 2012 or newer
/*
DECLARE @ErrorNumber INT = ERROR_NUMBER(),
@ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE();
RAISERROR(N'Msg %d: %s', 16, 1, @ErrorNumber, @ErrorMessage);
RETURN;
*/
END;
END CATCH;
GO
পরীক্ষা
DECLARE @ItemID INT;
EXEC dbo.GetOrInsertName
@SomeName = N'test1',
@ID = @ItemID OUTPUT;
SELECT @ItemID AS [ItemID];
GO
DECLARE @ItemID INT;
EXEC dbo.GetOrInsertName
@SomeName = N'test1',
@ID = @ItemID OUTPUT,
@TestRaceCondition = 1;
SELECT @ItemID AS [ItemID];
GO
ওপি থেকে প্রশ্ন
কেন এই চেয়ে ভাল MERGE
? ধারাটি TRY
ব্যবহার না করে আমি কি একই কার্যকারিতা পাব না WHERE NOT EXISTS
?
MERGE
বিভিন্ন "ইস্যু" রয়েছে (বেশ কয়েকটি তথ্যসূত্র @ এসকিউএলজিমের উত্তরে লিঙ্কযুক্ত তাই এখানে তথ্যটি নকল করার প্রয়োজন নেই)। এবং, এই পদ্ধতির কোনও অতিরিক্ত লকিং নেই (কম বিতর্ক), সুতরাং এটি একযোগে ভাল হওয়া উচিত। এই পদ্ধতির ক্ষেত্রে আপনি কখনই কোনও অনন্য বাধা লঙ্ঘন পাবেন না HOLDLOCK
, ইত্যাদি It's এটি কাজ করার পক্ষে যথেষ্ট গ্যারান্টিযুক্ত।
এই পদ্ধতির পিছনে যুক্তিটি হ'ল:
- আপনার যদি এই পদ্ধতির পর্যাপ্ত মৃত্যুদন্ড কার্যকর হয় যাতে আপনার সংঘর্ষের বিষয়ে চিন্তা করা দরকার, তবে আপনি চান না:
- প্রয়োজনের চেয়ে আরও বেশি পদক্ষেপ গ্রহণ করুন
- প্রয়োজনের চেয়ে বেশি সময় ধরে কোনও সংস্থানগুলিতে লক ধরে রাখুন
- যেহেতু সংঘর্ষগুলি কেবলমাত্র নতুন এন্ট্রিগুলিতেই ঘটতে পারে ( ঠিক একই সময়ে নতুন এন্ট্রি দাখিল করা হয় ),
CATCH
তাই প্রথম স্থানে ব্লকের মধ্যে পড়ার ফ্রিকোয়েন্সি বেশ কম হবে। কোডটি অপ্টিমাইজ করতে আরও বেশি অর্থবোধ তৈরি করে যা কোডের পরিবর্তে 99% সময় চালাবে যা 1% সময় চলবে (যদি না উভয়কেই অনুকূল করে তোলার জন্য কোনও ব্যয় না হয় তবে এখানে এটি হয় না)।
@ এসকিএলজিমের উত্তর থেকে মন্তব্য (জোর যুক্ত করা হয়েছে)
যখন সম্ভব হয় তখন তা এড়াতে আমি ব্যক্তিগতভাবে কোনও সমাধান চেষ্টা ও সমাধানটি পছন্দ করি । এই ক্ষেত্রে, আমি মনে করি না যে লকগুলি ব্যবহার serializable
করা একটি ভারী হাতের পদ্ধতির, এবং আমি আত্মবিশ্বাসী থাকব এটি উচ্চতর সম্মতিটি ভালভাবে পরিচালনা করবে।
আমি যদি এই প্রথম বাক্যটিকে "এবং _ যখন বুদ্ধিমান" হিসাবে সংশোধন করা হয় তবে আমি তার সাথে একমত হব। প্রযুক্তিগতভাবে কোনও কিছু সম্ভব হওয়ার কারণে এর অর্থ এই নয় যে পরিস্থিতি (অর্থাত্ ব্যবহারের ক্ষেত্রে) এর দ্বারা উপকৃত হবে।
আমি এই পদ্ধতির সাথে যে বিষয়টি দেখছি তা হ'ল এটি প্রস্তাবিত হওয়ার চেয়ে বেশি লক করে। "সিরিয়ালাইজযোগ্য" -তে উদ্ধৃত ডকুমেন্টেশনগুলি পুনরায় পড়া গুরুত্বপূর্ণ, বিশেষত নিম্নলিখিতটি (জোর দেওয়া হয়েছে):
- অন্যান্য লেনদেনগুলি মূল মান সহ নতুন সারি সন্নিবেশ করতে পারে না যা বর্তমান লেনদেন শেষ না হওয়া অবধি বর্তমান লেনদেনের যে কোনও বিবৃতি দ্বারা পঠিত কীগুলির পরিসরে পড়ে ।
এখন, উদাহরণ কোডটিতে মন্তব্যটি এখানে দেওয়া হয়েছে:
SELECT [Id]
FROM dbo.NameLookup WITH (SERIALIZABLE) /* hold that key range for @vName */
অপারেটিভ শব্দটি "ব্যাপ্তি" রয়েছে। লক নেওয়া হচ্ছে এটি কেবলমাত্র মানের উপর নয় @vName
, আরও সঠিকভাবে শুরু হওয়া একটি ব্যাপ্তিএই নতুন মানটি কোথায় যাবে সেই অবস্থানটি (যেমন নতুন মানটি যেখানে দু'দিকে বিদ্যমান মূল মানগুলির মধ্যে রয়েছে), তবে মানটি নিজেই নয়। অর্থ, বর্তমানে অনুসন্ধান করা মান (গুলি) এর উপর নির্ভর করে নতুন মানগুলি সন্নিবেশ করা থেকে অন্য প্রক্রিয়াগুলি অবরুদ্ধ করা হবে। যদি সীমাটির শীর্ষে অনুসন্ধান করা হচ্ছে, তবে সেই একই অবস্থানটি দখল করতে পারে এমন যে কোনও কিছু সন্নিবেশ করা অবরুদ্ধ করা হবে। উদাহরণস্বরূপ, যদি "a", "b" এবং "d" মানগুলি বিদ্যমান থাকে, তবে যদি একটি প্রক্রিয়া "f" তে নির্বাচন করে থাকে তবে মান "g" বা এমনকি "ই" সন্নিবেশ করা সম্ভব হবে না ( যেহেতু এর মধ্যে যে কোনও একটি "ডি" এর সাথে সাথেই আসবে)। তবে, "গ" এর মান সন্নিবেশ করা সম্ভব হবে কারণ এটি "সংরক্ষিত" ব্যাপ্তিতে স্থাপন করা হবে না।
নিম্নলিখিত আচরণে এই আচরণটি বর্ণনা করা উচিত:
(ক্যোরি ট্যাবে (অর্থাত্ সেশন) # 1)
INSERT INTO dbo.NameLookup ([ItemName]) VALUES (N'test5');
BEGIN TRAN;
SELECT [Id]
FROM dbo.NameLookup WITH (SERIALIZABLE) /* hold that key range for @vName */
WHERE ItemName = N'test8';
--ROLLBACK;
(ক্যোরি ট্যাবে (অর্থাত্ সেশন) # 2)
EXEC dbo.NameLookup_getset_byName @vName = N'test4';
-- works just fine
EXEC dbo.NameLookup_getset_byName @vName = N'test9';
-- hangs until you either hit "cancel" in this query tab,
-- OR issue a COMMIT or ROLLBACK in query tab #1
EXEC dbo.NameLookup_getset_byName @vName = N'test7';
-- hangs until you either hit "cancel" in this query tab,
-- OR issue a COMMIT or ROLLBACK in query tab #1
EXEC dbo.NameLookup_getset_byName @vName = N's';
-- works just fine
EXEC dbo.NameLookup_getset_byName @vName = N'u';
-- hangs until you either hit "cancel" in this query tab,
-- OR issue a COMMIT or ROLLBACK in query tab #1
একইভাবে, যদি মান "সি" বিদ্যমান থাকে এবং মান "এ" নির্বাচন করা হয় (এবং তাই লক করা হয়), তবে আপনি "ডি" এর মান সন্নিবেশ করতে পারেন, তবে "বি" এর মান নয়:
(ক্যোরি ট্যাবে (অর্থাত্ সেশন) # 1)
INSERT INTO dbo.NameLookup ([ItemName]) VALUES (N'testC');
BEGIN TRAN
SELECT [Id]
FROM dbo.NameLookup WITH (SERIALIZABLE) /* hold that key range for @vName */
WHERE ItemName = N'testA';
--ROLLBACK;
(ক্যোরি ট্যাবে (অর্থাত্ সেশন) # 2)
EXEC dbo.NameLookup_getset_byName @vName = N'testD';
-- works just fine
EXEC dbo.NameLookup_getset_byName @vName = N'testB';
-- hangs until you either hit "cancel" in this query tab,
-- OR issue a COMMIT or ROLLBACK in query tab #1
সত্যি কথা বলতে গেলে, আমার প্রস্তাবিত পদ্ধতির ক্ষেত্রে, যখন ব্যতিক্রম হয়, তখন লেনদেন লগের 4 টি প্রবেশ থাকবে যা এই "সিরিয়ালাইজযোগ্য লেনদেন" পদ্ধতির ক্ষেত্রে ঘটবে না। কিন্তু, আমি উপরে যেমন বলেছি, যদি ব্যতিক্রম সময়ের 1% (বা এমনকি 5%) ঘটে, তবে প্রাথমিকভাবে নির্বাচিত অস্থায়ীভাবে INSERT ক্রিয়াকলাপ অবরুদ্ধ করার সম্ভাব্য ক্ষেত্রে এর চেয়ে কম প্রভাব ফেলবে।
অপ্রাপ্তবয়স্ক হওয়া সত্ত্বেও, এই "সিরিয়ালাইজযোগ্য লেনদেন + OUTPUT ধারা" পদ্ধতির সাথে ইস্যুটি হ'ল OUTPUT
ধারাটি (এর বর্তমান ব্যবহারে) ফলাফল সেট হিসাবে ডেটা ফেরত পাঠায়। ফলাফলের সেটটিকে সাধারণ OUTPUT
প্যারামিটারের চেয়ে বেশি ওভারহেড (সম্ভবত উভয় পক্ষের: অভ্যন্তরীণ কার্সার পরিচালনা করার জন্য এসকিউএল সার্ভারে এবং অ্যাপ্লিকেশন স্তরে ডেটা রিডার অবজেক্টটি পরিচালনা করতে) প্রয়োজন হয় । প্রদত্ত যে আমরা কেবলমাত্র একটি একক স্কেলারের মান নিয়ে কাজ করছি এবং অনুমানটি মৃত্যুদণ্ড কার্যকর করার একটি উচ্চ ফ্রিকোয়েন্সি, ফলাফল সেটটির অতিরিক্ত ওভারহেড সম্ভবত যুক্ত করে।
এই OUTPUT
ধারাটি OUTPUT
প্যারামিটারটি ফেরত দেওয়ার মতোভাবে ব্যবহার করা যেতে পারে , এর জন্য অস্থায়ী টেবিল বা টেবিল ভেরিয়েবল তৈরি করতে অতিরিক্ত পদক্ষেপের প্রয়োজন হবে এবং তারপরে সেই টেম্প টেবিল / টেবিলের পরিবর্তনশীলটির মানটি OUTPUT
প্যারামিটারের মধ্যে বেছে নিতে হবে।
আরও স্পষ্টতা : সম্মতি এবং কার্য সম্পাদন সম্পর্কিত আমার বক্তব্যের @ এসকিএলজিমের প্রতিক্রিয়াতে (মূল উত্তরে) আমার প্রতিক্রিয়াতে @ এসকিএলজেমের জবাব (আপডেট উত্তর);
দুঃখিত, যদি এই অংশটি একটি সাম্প্রতিক বিট দীর্ঘ হয়, তবে এই মুহুর্তে আমরা দুটি পদ্ধতির সংক্ষেপে খুব নীচে আছি।
আমি বিশ্বাস করি যেভাবে তথ্য serializable
উপস্থাপন করা হয়েছে আসল প্রশ্নে উপস্থাপিত দৃশ্যে ব্যবহার করার সময় যে পরিমাণ লকিংয়ের মুখোমুখি হতে পারে তার সম্পর্কে ভুল ধারণা অনুধাবন করতে পারে ।
হ্যাঁ, আমি স্বীকার করব যে আমি পক্ষপাতদুষ্ট, যদিও তা ন্যায্য:
- কোনও মানুষের পক্ষে পক্ষপাতদুষ্ট না হওয়া অসম্ভব, কমপক্ষে কিছুটা কম ডিগ্রীতে এবং আমি এটিকে সর্বনিম্ন রাখার চেষ্টা করি,
- প্রদত্ত উদাহরণটি সরল ছিল, তবে এটি অত্যধিক জটিলতা ছাড়াই আচরণটি প্রকাশের উদাহরণস্বরূপ ছিল। অতিরিক্ত ফ্রিকোয়েন্সি বোঝানোর উদ্দেশ্য ছিল না, যদিও আমি বুঝতে পারি যে আমি স্পষ্টভাবে অন্যথায় বর্ণনাও করি নি এবং এটি আসলে উপস্থিত থেকে বড় সমস্যা বোঝাতেও পড়তে পারে। আমি নীচে এটি স্পষ্ট করার চেষ্টা করব।
- আমি দুটি বিদ্যমান কী ("ক্যোয়ারী ট্যাব 1" এবং "অনুসন্ধান ট্যাব 2" ব্লকের দ্বিতীয় সেট) এর মধ্যে একটি সীমা লক করার একটি উদাহরণও অন্তর্ভুক্ত করেছি।
- আমি আমার পদ্ধতির "লুকানো ব্যয়" খুঁজে পেয়েছি (এবং স্বেচ্ছাসেবক), যে প্রতিবার
INSERT
অনন্য বাধা লঙ্ঘনের কারণে চারটি অতিরিক্ত ট্রান লগ প্রবেশ করায় ব্যর্থ হয়। আমি অন্য উত্তর / পোস্টের কোনটিতে উল্লিখিত দেখিনি।
@ জিবিএন-এর "জেএফডিআই" পদ্ধতির বিষয়ে, মাইকেল জে স্বার্টের "উইলের জন্য কুৎসিত প্রগতিবাদ" পোস্ট, এবং মাইকের পোস্টের বিষয়ে অ্যারন বার্ট্র্যান্ডের মন্তব্য (তার পরীক্ষাগুলি কী দেখায় যে কর্মক্ষমতা হ্রাস পেয়েছে), এবং আপনার "মাইকেল জে অভিযোজিত সম্পর্কে মন্তব্য" স্টুয়ার্টের @ জিবিএন এর ট্রাই ক্যাচ জেএফডিআই পদ্ধতি "এর বর্ণনা অনুসারে অভিযোজিত:
আপনি যদি বিদ্যমান মানগুলি নির্বাচনের চেয়ে বেশি বার নতুন মান সন্নিবেশ করিয়ে থাকেন তবে এটি @ শ্রুতজকির সংস্করণের চেয়ে আরও বেশি পারফরম্যান্স হতে পারে। অন্যথায় আমি এই একের চেয়ে @ শ্রুতজকির সংস্করণটিকে পছন্দ করব।
"জেএফডিআই" পদ্ধতির সাথে সম্পর্কিত জিবিএন / মাইকেল / অ্যারন আলোচনার বিষয়ে, আমার পরামর্শকে জিবিএন-এর "জেএফডিআই" পদ্ধতির সাথে সমীকরণ করা ভুল হবে। "পান বা সন্নিবেশ" অপারেশন প্রকৃতির কারণে, কি একটি সুনির্দিষ্ট প্রয়োজন নেই SELECT
পেতে ID
বিদ্যমান রেকর্ডের জন্য মান। এই নির্বাচনটি IF EXISTS
চেক হিসাবে কাজ করে , যা এই পদ্ধতিরটিকে হারুনের পরীক্ষাগুলির "চেকট্রিচ্যাচ" পরিবর্তনের সাথে আরও সমান করে তোলে। মাইকেল এর পুনরায় লিখিত কোড (এবং মাইকেল এর অভিযোজন আপনার চূড়ান্ত অভিযোজন) এছাড়াও WHERE NOT EXISTS
প্রথম একই চেক করতে একটি অন্তর্ভুক্ত । সুতরাং, আমার পরামর্শ (মাইকেল এর চূড়ান্ত কোড এবং তার চূড়ান্ত কোড আপনার অভিযোজন সহ) আসলে CATCH
প্রায়শই এই ব্লকে আঘাত করবে না । এটি কেবল তখনই হতে পারে যেখানে দুটি সেশন,ItemName
INSERT...SELECT
ঠিক একই মুহুর্তে যেমন উভয় অধিবেশন ঠিক একই মুহুর্তে একটি "সত্য" পায় WHERE NOT EXISTS
এবং এইভাবে উভয়ই একই মুহূর্তে এটি করার চেষ্টা করে INSERT
। অন্য কোনও প্রক্রিয়া যখন একই মুহূর্তে এটি করার চেষ্টা করছে না তখন কোনও বিদ্যমান নির্বাচন করা ItemName
বা একটি নতুন সন্নিবেশ করানোর চেয়ে খুব সুনির্দিষ্ট দৃশ্যটি প্রায়শই ঘটে ItemName
যায় ।
সমস্ত মনে সহ: কেন আমি আমার পদ্ধতির পছন্দ করি?
প্রথমে, "সিরিয়ালাইজযোগ্য" পদ্ধতির মধ্যে লকিংয়ের কী ঘটে তা দেখা যাক। উপরে উল্লিখিত হিসাবে, "রেঞ্জ" যেটি লক হয়ে যায় তা নতুন কী মানটি ফিট করতে পারে তার উভয় পাশের বিদ্যমান কী মানগুলির উপর নির্ভর করে। সীমাটির সূচনা বা শেষের সূচি যথাক্রমে সূচকের শুরু বা শেষ হতে পারে, যদি সেই দিকে কোনও বিদ্যমান মূল মান না থাকে। ধরুন আমাদের কাছে নিম্নলিখিত সূচক এবং কী রয়েছে ( ^
সূচকের শুরুতে $
এটি শেষের প্রতিনিধিত্ব করে):
Range #: |--- 1 ---|--- 2 ---|--- 3 ---|--- 4 ---|
Key Value: ^ C F J $
সেশন 55 যদি এর মূল মান সন্নিবেশ করার চেষ্টা করে:
A
তারপর, # 1 (থেকে পরিসীমা ^
থেকে C
) লক করা আছে: অধিবেশন 56 মান ঢোকাতে পারেন না B
, এমনকি যদি অনন্য এবং বৈধ (এখনও)। কিন্তু সেশন 56 মান ঢোকাতে পারবেন D
, G
এবং M
।
D
তারপর, # 2 (থেকে পরিসীমা C
থেকে F
) লক করা আছে: অধিবেশন 56 মান ঢোকাতে পারেন না E
(এখনও)। কিন্তু সেশন 56 মান ঢোকাতে পারবেন A
, G
এবং M
।
M
তারপর, # 4 (থেকে পরিসীমা J
থেকে $
) লক করা আছে: অধিবেশন 56 মান ঢোকাতে পারেন না X
(এখনও)। কিন্তু সেশন 56 মান ঢোকাতে পারবেন A
, D
এবং G
।
আরও কী মূল্যবোধ যুক্ত হওয়ার সাথে সাথে মূল মানগুলির মধ্যে সীমাগুলি সংকীর্ণ হয়ে যায়, সুতরাং একই রেঞ্জের সাথে লড়াই করে একই সময়ে একাধিক মানের সন্নিবেশ হওয়ার সম্ভাবনা / ফ্রিকোয়েন্সি হ্রাস করে। স্বীকারযোগ্যভাবে, এটি কোনও বড় সমস্যা নয় এবং ভাগ্যক্রমে এটি এমন একটি সমস্যা হিসাবে দেখা যায় যা সময়ের সাথে প্রকৃতপক্ষে হ্রাস পায়।
আমার পদ্ধতির সমস্যাটি উপরে বর্ণিত ছিল: এটি কেবল তখন ঘটে যখন দুটি সেশন একই সময়ে একই কী মান সন্নিবেশ করানোর চেষ্টা করে । এই ক্ষেত্রে এটি নেমে আসে যার ঘটনার উচ্চতর সম্ভাবনা থাকে: দুটি ভিন্ন, তবুও নিকটবর্তী, মূল মান একই সাথে চেষ্টা করা হয়, বা একই মূল মান একই সাথে চেষ্টা করা হয়? আমি মনে করি উত্তরটি সন্নিবেশ করানোয় অ্যাপটির কাঠামোর মধ্যে রয়েছে তবে সাধারণভাবে বলতে গেলে আমি এটিকে আরও সম্ভবত এটি ধরে নেব যে দুটি ভিন্ন ভিন্ন মান যা কেবল একই পরিসীমা ভাগ করে নেওয়ার জন্য সন্নিবেশ করানো হচ্ছে। তবে সত্যিই জানার একমাত্র উপায় হ'ল উভয়ই ওপিএস সিস্টেমে পরীক্ষা করা।
এর পরে, দুটি পরিস্থিতি এবং প্রতিটি পদ্ধতির কীভাবে সেগুলি পরিচালনা করে তা বিবেচনা করা যাক:
সমস্ত অনুরোধগুলি অনন্য কী মানগুলির জন্য রয়েছে:
এই ক্ষেত্রে, CATCH
আমার প্রস্তাবিত ব্লকটি কখনই প্রবেশ করা হয় না, সুতরাং কোনও "ইস্যু" হয় না (অর্থাত্ 4 টি ট্রান লগ এন্ট্রি এবং এটি করতে যে সময় লাগে)। তবে, "সিরিয়ালাইজযোগ্য" পদ্ধতির মধ্যে, এমনকি সমস্ত সন্নিবেশ অনন্য হয়ে থাকলেও, সর্বদা একই পরিসরে অন্যান্য সন্নিবেশগুলি অবরুদ্ধ করার কিছুটা সম্ভাবনা থাকবে (যদিও এটি খুব দীর্ঘ নয়)।
একই মূল মানের জন্য অনুরোধের একই সময়ে উচ্চ-ফ্রিকোয়েন্সি:
এই ক্ষেত্রে - অস্তিত্বহীন মূল মানগুলির জন্য আগত অনুরোধগুলির ক্ষেত্রে স্বাতন্ত্র্যের খুব কম ডিগ্রী - CATCH
আমার পরামর্শের ব্লকটি নিয়মিত প্রবেশ করা হবে। এর প্রভাবটি হ'ল প্রতিটি ব্যর্থ সন্নিবেশকে অটো রোলব্যাক করতে হবে এবং লেনদেন লগটিতে 4 টি এন্ট্রি লিখতে হবে যা প্রতিবারের জন্য সামান্য পারফরম্যান্স হিট। তবে সামগ্রিক ক্রিয়াকলাপটি কখনই ব্যর্থ হয় না (কমপক্ষে এটির কারণে নয়)।
("আপডেটেড" পদ্ধতির পূর্ববর্তী সংস্করণে একটি সমস্যা ছিল যা এটিকে ডেডলকস থেকে ভোগার updlock
অনুমতি দেয় this এটি সমাধান করার জন্য একটি ইঙ্গিত যুক্ত করা হয়েছিল এবং এটি আর অচল অবস্থায় পড়ে না))কিন্তু, "সিরিয়ালাইজযোগ্য" পদ্ধতির (এমনকি আপডেট হওয়া, অপ্টিমাইজড সংস্করণে) অপারেশন অচল হয়ে যাবে। কেন? কারণ serializable
আচরণটি কেবল INSERT
পাঠ করা হয়েছে এবং তাই লক করা হয়েছে এমন সীমার ক্রিয়াকলাপকে বাধা দেয় ; এটি এই SELECT
ব্যাপ্তিতে অপারেশনগুলি আটকাবে না ।
serializable
পদ্ধতি, এই ক্ষেত্রে, কোন অতিরিক্ত ওভারহেড আছে বলে মনে হচ্ছে, এবং আমি যা পরামর্শ করছি চেয়ে সামান্য ভাল কার্য সম্পাদন করে হতে পারে।
পারফরম্যান্স সম্পর্কিত অনেক / সর্বাধিক আলোচনার সাথে সাথে, ফলাফলকে প্রভাবিত করতে পারে এমন অনেকগুলি কারণ থাকার কারণে, কিছু কীভাবে সঞ্চালিত হবে তা উপলব্ধি করার একমাত্র উপায় হ'ল লক্ষ্য পরিবেশে এটি চালানো হবে যেখানে চেষ্টা করা try এই মুহুর্তে এটি মতের বিষয় হবে না :)।