এসকিএল সার্ভারে, নির্বাচিত একটি গ্রুপের সারি লক করা আছে কিনা তা পরীক্ষা করার কোনও উপায় আছে?


21

আমরা বহু বিলিয়ন সারি সারণীতে প্রচুর রেকর্ড আপডেট / মুছে ফেলার চেষ্টা করছি। যেহেতু এটি একটি জনপ্রিয় টেবিল, তাই এই টেবিলের বিভিন্ন বিভাগে প্রচুর ক্রিয়াকলাপ রয়েছে। যে কোনও বৃহত আপডেট / মুছুন ক্রিয়াকলাপ বর্ধিত সময়ের জন্য অবরুদ্ধ করা হচ্ছে (যেহেতু এটি সমস্ত সারি বা পৃষ্ঠা লক বা টেবিল লকটিতে লক পাওয়ার জন্য অপেক্ষা করছে) যার ফলে সময় শেষ হয়ে যায় বা কার্য শেষ করতে একাধিক দিন সময় নেয়।

সুতরাং, আমরা একই সময়ে সারিগুলির ছোট ব্যাচ মোছার পদ্ধতির পরিবর্তন করছি। তবে আমরা যাচাই করতে চাই (নির্বাচিতদের 100 বা 1000 বা 2000 সারি বলা যাক) বর্তমানে কোনও আলাদা প্রক্রিয়া দ্বারা লক হয়েছে কিনা।

  • যদি তা না হয় তবে মুছুন / আপডেট করুন proceed
  • যদি সেগুলি লক করা থাকে, তবে পরবর্তী রেকর্ডগুলির গোষ্ঠীতে যান।
  • শেষে, শুরুতে ফিরে আসুন এবং বামদিকগুলি আপডেট / মোছার চেষ্টা করুন।

এটা কি করণীয়?

ধন্যবাদ, টি.সি.


2
আপনি মুছে ফেলা বিবৃতি বা NOWAIT (পুরো গ্রুপ ব্যর্থ করতে) এর অংশ হিসাবে READPAST এ সন্ধান করেছেন? এর মধ্যে একটি আপনার পক্ষে কাজ করতে পারে। msdn.microsoft.com/en-us/library/ms187373.aspx
শান বলে

@ সানগ্যালার্ডি আমি এই ধারণাটি বিবেচনা করি নি, তবে এখনই করব। তবে কোনও নির্দিষ্ট সারিটি লক হয়েছে কিনা তা পরীক্ষা করার আরও সহজ উপায় আছে কি? ধন্যবাদ।
টোকি

3
এছাড়াও আপনি LOCK_TIMEOUT (দেখব পারে msdn.microsoft.com/en-us/library/ms189470.aspx )। উদাহরণস্বরূপ, অ্যাডাম মাচানিকের এসপি_হোসিএকটিভ এই পদ্ধতিটি নিশ্চিত করে যে কার্যকর করার পরিকল্পনা সংগ্রহ করার চেষ্টা করার সময় যদি প্রক্রিয়াটি ব্লক করা থাকে তবে এটি খুব বেশি সময় অপেক্ষা করবে না। আপনি একটি সংক্ষিপ্ত সময়সীমা নির্ধারণ করতে পারেন বা এমনকি 0 এর মান ব্যবহার করতে পারেন ("0 এর অর্থ একবারে অপেক্ষা না করা এবং লকটি আসার সাথে সাথে একটি বার্তা ফিরে আসা to") ত্রুটিটি ধরতে আপনি এটি TRY / CATCH এর সাথে সংযুক্ত করতে পারেন 1222 ( "লক অনুরোধের সময়সীমা পেরিয়ে গেছে") এবং পরবর্তী ব্যাচে এগিয়ে যান।
জেফ প্যাটারসন

@ জিপ্টারসন আকর্ষণীয় পন্থা। আমিও এটি চেষ্টা করব।
টোকি

2
উত্তর দেওয়ার জন্য, অ্যাপ্লিকেশনটিতে বিশেষভাবে কিছু না করা থাকলে সারিগুলি লক করা আছে কিনা তা দেখার সহজ উপায় নেই। মূলত আপনি প্রথমে একটি হোল্ডলক এবং এক্সলোকের সাথে একটি লক_টাইমআউট সেট (যা আমার মূল মন্তব্যে NOWAIT সম্পর্কে, টাইম আউট 0 এ সেট করে) দিয়ে একটি নির্বাচন করতে পারেন। যদি আপনি এটি না পান তবে আপনি জানেন যে কিছু লক হয়েছে। "কোনও বিষয় দ্বারা সূচক জেড লক করা ব্যবহার করে টেবিল ওয়াইতে ইজ রো এক্স এক্স" বলে সহজেই কিছু পাওয়া যায় না । আমরা দেখতে পাচ্ছি যে টেবিলটিতে লক রয়েছে বা কোনও পৃষ্ঠা / সারি / কী / ইত্যাদি আছে লক রয়েছে তবে এটি কোনও প্রশ্নের সুনির্দিষ্ট সারিগুলিতে অনুবাদ করা সহজ হবে না।
শন বলে 21-21

উত্তর:


10

যদি আমি অনুরোধটি সঠিকভাবে বুঝতে পারি তবে লক্ষ্যটি সারিগুলির ব্যাচগুলি মুছে ফেলা হয়, একই সময়ে, ডিএমএল অপারেশনগুলি সারণীতে পুরো সারিগুলিতে ঘটে থাকে। লক্ষ্যটি একটি ব্যাচ মুছে ফেলা; যাইহোক, যদি বলা ব্যাচের দ্বারা নির্ধারিত সীমার মধ্যে থাকা কোনও অন্তর্নিহিত সারিগুলি লক করা থাকে, তবে আমাদের অবশ্যই সেই ব্যাচটি এড়িয়ে গিয়ে পরবর্তী ব্যাচে চলে যেতে হবে। এরপরে আমাদের অবশ্যই এমন কোনও ব্যাচগুলিতে ফিরে যেতে হবে যা পূর্বে মুছে ফেলা হয়নি এবং আমাদের মূল মোছার যুক্তিকে আবার চেষ্টা করতে হবে। সারিগুলির সমস্ত প্রয়োজনীয় ব্যাচগুলি মোছা না হওয়া পর্যন্ত আমাদের অবশ্যই এই চক্রটি পুনরাবৃত্তি করতে হবে।

যেমনটি উল্লেখ করা হয়েছে, অবরুদ্ধ সারিগুলি থাকতে পারে এমন অতীত রেঞ্জগুলি এড়ানোর জন্য একটি READPAST ইঙ্গিত এবং রিড কমিটি (ডিফল্ট) বিচ্ছিন্নতা স্তরটি ব্যবহার করা যুক্তিসঙ্গত। আমি আরও একধাপ এগিয়ে গিয়ে সিরিয়ালিজেবল বিচ্ছিন্নতা স্তর এবং নিবিলিং মুছে ফেলা ব্যবহার করার পরামর্শ দেব।

এসকিউএল সার্ভার সিরিয়ালাইজযোগ্য লেনদেনের বিচ্ছিন্নতা স্তরটি ব্যবহার করার সময় লেনদেন-এসকিউএল বিবৃতি দ্বারা পড়া একটি রেকর্ড সেটটিতে স্পষ্টভাবে অন্তর্ভুক্ত থাকা সারিগুলির সীমাবদ্ধতার সুরক্ষার জন্য কী-রেঞ্জের লকগুলি ব্যবহার করে ... আরও এখানে সন্ধান করুন: https://technet.microsoft.com /en-US/library/ms191272(v=SQL.105).aspx

নিবলিলিং ডিলিটগুলি সহ, আমাদের লক্ষ্য হ'ল সারিগুলির বিস্তৃতি বিচ্ছিন্ন করা এবং নিশ্চিত করা যায় যে আমরা যখন সারিগুলি মুছে ফেলছি তখন সেই সারিগুলিতে কোনও পরিবর্তন ঘটবে না, অর্থাত্ আমরা ফ্যানটম পড়ি বা সন্নিবেশ চাই না। সিরিয়ালাইজযোগ্য বিচ্ছিন্নতা স্তরটি এই সমস্যাটি সমাধান করার জন্য।

আমি আমার সমাধানটি প্রদর্শন করার আগে, আমি এটি যুক্ত করতে চাই যে আমি আপনার ডাটাবেসের ডিফল্ট বিচ্ছিন্নতা স্তরকে সিরিয়ালিজেবলের দিকে সরিয়ে দেওয়ার পরামর্শ দিচ্ছি না বা আমি প্রস্তাব দিচ্ছি না যে আমার সমাধানটি সবচেয়ে ভাল। আমি কেবল এটি উপস্থাপন করতে চাই এবং দেখতে চাই যে আমরা এখান থেকে কোথায় যেতে পারি।

কয়েকটি ঘরে রাখার নোট:

  1. আমি যে এসকিউএল সার্ভার সংস্করণটি ব্যবহার করছি তা হ'ল মাইক্রোসফ্ট এসকিউএল সার্ভার 2012 - 11.0.5343.0 (এক্স 64)
  2. আমার পরীক্ষার ডাটাবেস সম্পূর্ণ পুনরুদ্ধার মডেলটি ব্যবহার করছে

আমার পরীক্ষা শুরু করতে, আমি একটি পরীক্ষামূলক ডাটাবেস, একটি নমুনা সারণী স্থাপন করব এবং আমি সারণিটি 2,000,000 সারি দ্বারা পূরণ করব।


USE [master];
GO

SET NOCOUNT ON;

IF DATABASEPROPERTYEX (N'test', N'Version') > 0
BEGIN
    ALTER DATABASE [test] SET SINGLE_USER
        WITH ROLLBACK IMMEDIATE;
    DROP DATABASE [test];
END
GO

-- Create the test database
CREATE DATABASE [test];
GO

-- Set the recovery model to FULL
ALTER DATABASE [test] SET RECOVERY FULL;

-- Create a FULL database backup
-- in order to ensure we are in fact using 
-- the FULL recovery model
-- I pipe it to dev null for simplicity
BACKUP DATABASE [test]
TO DISK = N'nul';
GO

USE [test];
GO

-- Create our table
IF OBJECT_ID('dbo.tbl','U') IS NOT NULL
BEGIN
    DROP TABLE dbo.tbl;
END;
CREATE TABLE dbo.tbl
(
      c1 BIGINT IDENTITY (1,1) NOT NULL
    , c2 INT NOT NULL
) ON [PRIMARY];
GO

-- Insert 2,000,000 rows 
INSERT INTO dbo.tbl
    SELECT TOP 2000
        number
    FROM
        master..spt_values
    ORDER BY 
        number
GO 1000

এই মুহুর্তে, আমাদের এক বা একাধিক সূচকের প্রয়োজন হবে যার উপর সিরিয়ালিজেবল বিচ্ছিন্নতা স্তরের লকিং প্রক্রিয়াগুলি কাজ করতে পারে।


-- Add a clustered index
CREATE UNIQUE CLUSTERED INDEX CIX_tbl_c1
    ON dbo.tbl (c1);
GO

-- Add a non-clustered index
CREATE NONCLUSTERED INDEX IX_tbl_c2 
    ON dbo.tbl (c2);
GO

এখন, আমাদের 2000,000 সারি তৈরি হয়েছিল তা পরীক্ষা করে দেখুন to


SELECT
    COUNT(*)
FROM
    tbl;

এখানে চিত্র বর্ণনা লিখুন

সুতরাং, আমাদের আমাদের ডাটাবেস, টেবিল, সূচী এবং সারি রয়েছে। সুতরাং, আসুন নিবলিলিং মুছে ফেলার জন্য পরীক্ষাটি সেট আপ করি। প্রথমে, আমাদের অবশ্যই সিদ্ধান্ত নিতে হবে যে একটি সাধারণ নিবিলিং মুছিয়া প্রক্রিয়া কীভাবে তৈরি করা যায়।


DECLARE
      @BatchSize        INT    = 100
    , @LowestValue      BIGINT = 20000
    , @HighestValue     BIGINT = 20010
    , @DeletedRowsCount BIGINT = 0
    , @RowCount         BIGINT = 1;

SET NOCOUNT ON;
GO

WHILE  @DeletedRowsCount <  ( @HighestValue - @LowestValue ) 
BEGIN

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    BEGIN TRANSACTION

        DELETE 
        FROM
            dbo.tbl 
        WHERE
            c1 IN ( 
                    SELECT TOP (@BatchSize)
                        c1
                    FROM
                        dbo.tbl 
                    WHERE 
                        c1 BETWEEN @LowestValue AND @HighestValue
                    ORDER BY 
                        c1
                  );

        SET @RowCount = ROWCOUNT_BIG();

    COMMIT TRANSACTION;

    SET @DeletedRowsCount += @RowCount;
    WAITFOR DELAY '000:00:00.025';
    CHECKPOINT;

END;

আপনি দেখতে পাচ্ছেন, আমি স্পষ্ট লেনদেনটি ওয়েল লুপের মধ্যে রেখেছি। আপনি যদি লগ ফ্লাশকে সীমাবদ্ধ করতে চান তবে লুপের বাইরে নির্দ্বিধায় তা অনুভব করুন। তদুপরি, যেহেতু আমরা সম্পূর্ণ পুনরুদ্ধার মডেলটিতে আছি, তাই আপনার ল্যাবিলিং অপসারণের ক্রিয়াকলাপ চালানোর সময় আপনি আরও প্রায়ই লেনদেনের লগ ব্যাকআপ তৈরি করতে ইচ্ছুক হতে পারেন যাতে আপনার লেনদেনের লগটিকে অতিমাত্রায় বাড়ার হাত থেকে রোধ করা যায়।

সুতরাং, এই সেটআপটি দিয়ে আমার বেশ কয়েকটি লক্ষ্য রয়েছে। প্রথমত, আমি আমার কী-রেঞ্জের লকগুলি চাই; সুতরাং, আমি ব্যাচগুলি যতটা সম্ভব ছোট রাখার চেষ্টা করি। আমি আমার "বিশাল" টেবিলের উপর negativeণাত্মক সামঞ্জস্যকে প্রভাবিত করতে চাই না; সুতরাং, আমি আমার লকগুলি নিতে এবং এগুলি যত দ্রুত সম্ভব ছেড়ে দিতে চাই। সুতরাং, আমি আপনাকে আপনার ব্যাচের আকার ছোট করার প্রস্তাব দিই।

এখন, আমি কার্যকরভাবে এই মোছার রুটিনের খুব সংক্ষিপ্ত উদাহরণ সরবরাহ করতে চাই। আমাদের অবশ্যই এসএসএমএসের মধ্যে একটি নতুন উইন্ডো খুলতে হবে এবং আমাদের টেবিল থেকে একটি সারি মুছে ফেলতে হবে। আমি এটি ডিফল্ট READ COMMITTED বিচ্ছিন্নতা স্তরটি ব্যবহার করে নিখুঁত লেনদেনের মধ্যে করব।


DELETE FROM
    dbo.tbl
WHERE
    c1 = 20005;

এই সারিটি কি আসলে মুছে ফেলা হয়েছিল?


SELECT
    c1
FROM
    dbo.tbl
WHERE
    c1 BETWEEN 20000 AND 20010;

হ্যাঁ, এটি মুছে ফেলা হয়েছিল।

মুছে ফেলা সারিটির প্রমাণ

এখন, আমাদের লকগুলি দেখতে, এসএসএমএসের মধ্যে একটি নতুন উইন্ডো খুলুন এবং একটি বা দুটি কোড স্নিপেট যুক্ত করুন add আমি অ্যাডাম মেকানিকের এসপি_জয়েটিসটিভ ব্যবহার করছি, যা এখানে পাওয়া যাবে: sp_Woisactive


SELECT
    DB_NAME(resource_database_id) AS DatabaseName
  , resource_type
  , request_mode
FROM
    sys.dm_tran_locks
WHERE
    DB_NAME(resource_database_id) = 'test'
    AND resource_type = 'KEY'
ORDER BY
    request_mode;

-- Our insert
sp_lock 55;

-- Our deletions
sp_lock 52;

-- Our active sessions
sp_whoisactive;

এখন, আমরা শুরু করতে প্রস্তুত। একটি নতুন এসএসএমএস উইন্ডোতে আসুন আমরা একটি স্পষ্ট লেনদেন শুরু করি যা আমরা মুছে ফেলা এক সারিটি পুনরায় toোকানোর চেষ্টা করবে। একই সাথে, আমরা আমাদের নিবিলিং মুছুন অপারেশন বন্ধ করব।

সন্নিবেশ কোড:


BEGIN TRANSACTION

    SET IDENTITY_INSERT dbo.tbl ON;

    INSERT  INTO dbo.tbl
            ( c1 , c2 )
    VALUES
            ( 20005 , 1 );

    SET IDENTITY_INSERT dbo.tbl OFF;

--COMMIT TRANSACTION;

আসুন inোকানো দিয়ে শুরু করে আমাদের মোছার পরে দুটি ক্রিয়াকলাপ শুরু করি। আমরা কী-রেঞ্জের লক এবং একচেটিয়া লক দেখতে পারি।

ব্যাপ্তি এবং এক্সক্লুসিভ লক্স

সন্নিবেশ এই লকগুলি উত্পন্ন:

Sertোকান লকস

নিবলিং ডিলিট / সিলেক্ট করা এই লকগুলি ধারণ করে:

এখানে চিত্র বর্ণনা লিখুন

আমাদের সন্নিবেশ প্রত্যাশার মতো আমাদের মুছতে বাধা দিচ্ছে:

সন্নিবেশ করুন ব্লক মুছুন

এখন আসুন, সন্নিবেশ লেনদেন প্রতিশ্রুতিবদ্ধ এবং দেখুন কি হয়।

মুছে ফেলুন প্রতিশ্রুতিবদ্ধ

এবং যেমন প্রত্যাশা করা হয়েছে, সমস্ত লেনদেন সম্পূর্ণ। এখন, আমাদের অবশ্যই সন্নিবেশটি ভুত ছিল কিনা তা মুছে ফেলা উচিত বা মুছে ফেলা অপারেশনটি এটিও সরিয়ে দিয়েছে কিনা তা দেখতে।


SELECT
    c1
FROM
    dbo.tbl
WHERE
    c1 BETWEEN 20000 AND 20015;

আসলে, সন্নিবেশটি মোছা হয়েছে; সুতরাং, কোনও ভ্যান্ট inোকানোর অনুমতি দেওয়া হয়নি।

কোনও ফ্যান্টম sertোকানো হয়নি

সুতরাং, উপসংহারে, আমি মনে করি যে এই অনুশীলনের আসল উদ্দেশ্যটি প্রতিটি একক সারি, পৃষ্ঠা, বা টেবিল-স্তরের লকটি চেষ্টা এবং ট্র্যাক করা এবং কোনও ব্যাচের উপাদানকে লক করা আছে কিনা তা নির্ধারণ করার চেষ্টা করা এবং তাই আমাদের মুছে ফেলা অপারেশনটির প্রয়োজন হবে অপেক্ষা করুন। এটাই হতে পারে প্রশ্নকারীদের অভিপ্রায়; তবে, সেই কাজটি অসম্ভব এবং অসম্ভব যদি না হয় তবে মূলত অবৈজ্ঞানিক। আসল লক্ষ্য হ'ল এটি নিশ্চিত করা যে কোনও বার আমরা আমাদের ব্যাচের পরিসরকে আমাদের নিজস্ব তালা দিয়ে আলাদা করে ফেলেছি এবং তারপরে ব্যাচটি মুছে ফেলার আগে কোনও অনাকাঙ্ক্ষিত ঘটনা না ঘটে। গুরুতর বিচ্ছিন্নতা স্তর এই লক্ষ্য অর্জন করে। মূলটি হ'ল আপনার নিবলগুলি ছোট রাখা, আপনার লেনদেনের লগ নিয়ন্ত্রণে রাখা এবং অযাচিত ঘটনাগুলি নির্মূল করা।

আপনি যদি গতি চান, তবে বিশালাকার মতো গভীর সারণীগুলি তৈরি করবেন না যা পার্টিশন করা যায় না এবং তাই দ্রুত ফলাফলের জন্য পার্টিশন স্যুইচিং ব্যবহার করতে অক্ষম হন। গতির মূল কথাটি পার্টিশন এবং সমান্তরালতা; ভোগান্তির মূল চাবিকাঠিটি হ'ল নিমক এবং লাইভ লকিং।

আপনি কী মনে করেন দয়া করে আমাকে জানান।

আমি ক্রিয়াকলাপের বিচ্ছিন্নতা স্তরের আরও কয়েকটি উদাহরণ তৈরি করেছি। সেগুলি নীচের লিঙ্কগুলিতে পাওয়া উচিত।

অপারেশন মুছুন

অপারেশন sertোকান

ইক্যুয়ালিটি অপারেশনস - পরবর্তী মূল মানগুলিতে কী-রেঞ্জের লক

ইক্যুয়ালিটি অপারেশনস - বিদ্যমান ডেটাগুলির একক ফলক

ইক্যুয়ালিটি অপারেশনস - অস্তিত্বহীন ডেটার একক সংগ্রহ

বৈষম্য অপারেশনস - রেঞ্জ এবং পরবর্তী কী মানগুলিতে কী-রেঞ্জ লক


9

সুতরাং, আমরা একই সময়ে সারিগুলির ছোট ব্যাচ মোছার পদ্ধতির পরিবর্তন করছি।

ছোট যত্নশীল ব্যাচ বা খণ্ডগুলিতে মুছতে এটি সত্যিই ভাল ধারণা । আমি একটি ছোট যোগ করব waitfor delay '00:00:05'এবং ডাটাবেসের পুনরুদ্ধারের মডেলের উপর নির্ভর করে - যদি FULL, তবে ব্যাচের মধ্যে লেনদেনের লগটি ফুলে যাওয়া এড়ানোর জন্য একটি করুন log backupএবং যদি SIMPLEতাই করেন manual CHECKPOINT

তবে আমরা যাচাই করতে চাই (নির্বাচিতদের 100 বা 1000 বা 2000 সারি বলা যাক) বর্তমানে কোনও আলাদা প্রক্রিয়া দ্বারা লক হয়েছে কিনা।

আপনি যা বলছেন তা সম্পূর্ণরূপে বাক্সের বাইরে সম্ভব নয় (আপনার 3 বুলেট পয়েন্টগুলি মাথায় রেখে)। উপরের পরামর্শটি - small batches + waitfor delayযদি কাজ না করে (তবে আপনি সঠিক পরীক্ষা-নিরীক্ষা করেন) তবে আপনি এটি ব্যবহার করতে পারেন query HINT

ব্যবহার করবেন না NOLOCK- কেবি / 308886 , ইতজিক বেন- গানের দ্বারা এসকিউএল সার্ভারের পঠন-ধারাবাহিকতার সমস্যাগুলি দেখুন , সর্বত্র নোলক লাগানো - অ্যারন বারট্র্যান্ড এবং এসকিউএল সার্ভার নলক ইঙ্গিত এবং অন্যান্য দুর্বল ধারণাগুলি দেখুন

READPASTইঙ্গিতটি আপনার দৃশ্যে সহায়তা করবে। READPASTইঙ্গিতটির সূচনাটি হ'ল - যদি কোনও সারি স্তরের লক থাকে তবে এসকিউএল সার্ভার এটি পড়বে না।

সুনির্দিষ্ট করে যে ডেটাবেস ইঞ্জিন অন্যান্য লেনদেনের দ্বারা লক হওয়া সারিগুলি পড়েনি। READPASTনির্দিষ্ট করা হলে সারি-স্তরের লকগুলি এড়িয়ে যায়। এটি হ'ল, ডাটাবেস ইঞ্জিন লকগুলি প্রকাশ না হওয়া অবধি বর্তমান লেনদেনকে অবরুদ্ধ করার পরিবর্তে সারিগুলি পেরিয়ে যায়।

আমার সীমাবদ্ধ পরীক্ষার সময়, DELETE from schema.tableName with (READPAST, READCOMMITTEDLOCK)কোয়েরি সেশন বিচ্ছিন্নতা স্তরটি যেভাবেই ডিফল্ট বিচ্ছিন্নতা স্তরটি READ COMMITTEDব্যবহার করে সেট করতে এবং সেট করার সময় আমি সত্যিই ভাল থ্রুপুট পেয়েছি SET TRANSACTION ISOLATION LEVEL READ COMMITTED


2

মূলত প্রশ্নের মন্তব্যে দেওয়া অন্যান্য পদ্ধতির সংক্ষিপ্তসার ।


  1. NOWAITকোনও বেমানান লকটি আসার সাথে সাথে কাঙ্ক্ষিত আচরণটি পুরো খণ্ডটি ব্যর্থ করতে ব্যবহার করুন ।

    NOWAITডকুমেন্টেশন থেকে :

    টেবিলে লক আসার সাথে সাথে একটি বার্তা ফেরত দেওয়ার জন্য ডাটাবেস ইঞ্জিনকে নির্দেশ দেয়। নির্দিষ্ট টেবিলের জন্য নির্দিষ্ট করার NOWAITসমতুল্য SET LOCK_TIMEOUT 0NOWAITযখন ইঙ্গিতটি কাজ করে না TABLOCKইঙ্গিতটি এছাড়াও অন্তর্ভুক্ত করা হয়। TABLOCKইঙ্গিতটি ব্যবহার করার সময় অপেক্ষা না করেই কোনও কোয়েরিটি শেষ করতে , SETLOCK_TIMEOUT 0;পরিবর্তে কোয়েরিটি প্রিফেস করুন ।

  2. SET LOCK_TIMEOUTঅনুরূপ ফলাফল অর্জন করতে ব্যবহার করুন তবে একটি কনফিগারযোগ্য সময়সীমা সহ:

    ডকুমেন্টেশন থেকেSET LOCK_TIMEOUT

    একটি বিবৃতি একটি লক প্রকাশের জন্য অপেক্ষা করে এমন মিলিসেকেন্ডগুলির সংখ্যা উল্লেখ করে।

    যখন কোনও লকের জন্য অপেক্ষা সময়সীমা ছাড়িয়ে যায় তখন একটি ত্রুটি ফিরে আসে। 0 এর মান বলতে কিছুক্ষণ অপেক্ষা না করা এবং কোনও লক আসার সাথে সাথে একটি বার্তা ফিরে পাওয়া।


0

ধরে নিতে আমাদের কাছে 2 টি সমান্তরাল প্রশ্ন রয়েছে:

সংযোগ / অধিবেশন 1: সারিটি লক হয়ে যাবে = 777

SELECT * FROM your_table WITH(UPDLOCK,READPAST) WHERE id = 777

সংযুক্ত / সেশন 2: লক করা সারিটি = 777 উপেক্ষা করবে

SELECT * FROM your_table WITH(UPDLOCK,READPAST) WHERE id = 777

অথবা সংযুক্ত / সেশন 2: ব্যতিক্রম ছুঁড়ে ফেলবে

DECLARE @id integer;
SELECT @id = id FROM your_table WITH(UPDLOCK,READPAST) WHERE id = 777;
IF @id is NULL
  THROW 51000, 'Hi, a record is locked or does not exist.', 1;

-1

ভালো কিছু উপর ফিল্টারিং ব্যবহার করে দেখুন - এটা করতে আরো জটিল হতে আপনি কি সত্যিই, সত্যিই নির্দিষ্ট পেতে চান। Sys.dm_tran_locks এর বর্ণনার জন্য বিওএল দেখুন

SELECT 
tl.request_session_id,
tl.resource_type,
tl.resource_associated_entity_id,
db_name(tl.resource_database_id) 'Database',
CASE 
    WHEN tl.resource_type = 'object' THEN object_name(tl.resource_associated_entity_id, tl.resource_database_id)
    ELSE NULL
END 'LockedObject',
tl.resource_database_id,
tl.resource_description,
tl.request_mode,
tl.request_type,
tl.request_status FROM [sys].[dm_tran_locks] tl WHERE resource_database_id <> 2order by tl.request_session_id

শুধু কৌতূহলী - কেন ডাউনটা?
রটেনজেক

-11

আপনি মোছার সময় আপনি নলোক্ক ব্যবহার করতে পারেন এবং সারিগুলি লক করা থাকলে সেগুলি মোছা হবে না। এটি আদর্শ নয় তবে আপনার জন্য কৌশলটি করতে পারে।

DELETE TA FROM dbo.TableA TA WITH (NOLOCK) WHERE Condition = True

7
যদি আমি আমার স্থানীয় মেশিন আমি পেতে চেষ্টা যে Msg 1065, Level 15, State 1, Line 15 The NOLOCK and READUNCOMMITTED lock hints are not allowed for target tables of INSERT, UPDATE, DELETE or MERGE statements., 2005 সাল থেকে অবচিত
টিম মনিকা - টম ভী
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.