সূচী লক ক্রমের কারণে দুটি আপডেটে এসকিউএল সার্ভার ডেডলক


11

আমার দুটি আপডেট রয়েছে - একটি প্রথমে সিআই এবং তারপরে এনসিআই (স্ট্যাটাসে) লক করে কারণ স্থিতি কলামটিও আপডেট করা হচ্ছে। অন্যটি ইতিমধ্যে এনসআইতে একটি ইউ লকটির মালিক কারণ এটি জানে যে এটি পরিবর্তন হচ্ছে এবং তারপরে সিআই-তে একটি ইউ লক পাওয়ার চেষ্টা করে।

এগুলি সিরিয়ালায়িত করতে বাধ্য করার সহজতম উপায় কী? এটি একটি টেবিল-স্তরের ইঙ্গিতটি ব্যবহার করা অদ্ভুত বলে মনে হচ্ছে যেহেতু এটি একটি অভ্যন্তরীণ সূচকের বিষয় - এতে কেবল একটি সারণী জড়িত - আপলোডকৃত, হোল্ডলক স্বয়ংক্রিয়ভাবে কেবলমাত্র সেই টেবিলের প্রয়োজনীয় সমস্ত সূচীতে প্রয়োগ হবে এবং এরপরে এটি সিরিয়ালায়িত করতে বাধ্য করবে?

এখানে প্রশ্নগুলি:

UPDATE htt_action_log
SET status = 'ABORTED', CLOSED = GETUTCDATE()
WHERE transition_uuid = '{F53ADDDA-E46B-4726-66D8-D7B640B66597}'
AND status = 'OPEN';

সেই এক এক্স সিআই-তে সারিটি লক করে (তৈরি কলামে) এবং তারপরে এনসিআইতে এক্স লক করার চেষ্টা করে যা স্থিতি কলামটি অন্তর্ভুক্ত করে।

UPDATE htt_action_log
SET status = 'RUNNING {36082BCD-EB52-4358-E3D3-4D96FD5B9F0F} 1360094342'
WHERE action_uuid = (SELECT TOP 1 action_uuid
                     FROM htt_action_log
                     WHERE transition_uuid = '{F53ADDDA-E46B-4726-66D8-D7B640B66597}'
                         AND status = 'OPEN'
                     ORDER BY action_seq)

এই এক ইউ একই এনসিআইকে লক করে - আমার ধারণা করা নেস্টেড ক্যোয়ারির জন্য, তারপরে আপডেটের জন্য সিআই লক করতে যায়।

এই অর্ডার অচলাবস্থা উত্পাদন করে।

সহজ সমাধান হ'ল দুটি প্রশ্নের সম্পূর্ণরূপে অবরুদ্ধকরণ - অর্থাৎ সিরিয়ালাইজ করা। জোর করার সহজতম উপায়টি কী, কেবল WITH (UPDLOCK, HOLDLOCK)সারণির রেফারেন্সগুলি রাখুন (প্রথমটিতে একটি এবং দ্বিতীয়টিতে দুটি)?

DDL:

নোট ক্লায়েন্টের এই টেবিলটিতে আরও সূচি রয়েছে যা এই আপডেট দ্বারা প্রভাবিত হওয়া উচিত, তবে ডেডলক গ্রাফে উল্লেখ করা হয়নি।

CREATE TABLE [dbo].[HTT_ACTION_LOG](
    [ACTION_UUID] [varchar](128) NOT NULL,
    [TRANSITION_UUID] [varchar](128) NOT NULL,
    [STATUS] [varchar](128) NOT NULL,
    [CREATED] [datetime] NOT NULL,
    [CLOSED] [datetime] NULL,
    [ACTION_SEQ] [int] NOT NULL,
    [ACTION_TYPE] [varchar](15) NOT NULL,
    [ACTION_NAME] [varchar](50) NOT NULL,
    [ACTION_RESULT] [varchar](8000) NULL,
    [PENDING_SINCE] [datetime] NULL,
    [ACTION_SQL] [varchar](8000) NULL,
    [ERROR_OK] [int] NULL,
    [ERROR_COND] [varchar](2048) NULL,
    [RETRY] [varchar](128) NULL,
 CONSTRAINT [PK_HTT_ACTION_LOG_1] UNIQUE NONCLUSTERED 
(
    [ACTION_UUID] ASC
)
)

CREATE CLUSTERED INDEX [IK_HTT_ACTION_LOG_2] ON [dbo].[HTT_ACTION_LOG] 
(
    [CREATED] ASC
)

CREATE NONCLUSTERED INDEX [IK_HTT_ACTION_LOG_1] ON [dbo].[HTT_ACTION_LOG] 
(
    [TRANSITION_UUID] ASC,
    [STATUS] ASC
)
INCLUDE ( [ACTION_UUID],
[ACTION_SEQ])

CREATE NONCLUSTERED INDEX [IK_HTT_ACTION_LOG_4] ON [dbo].[HTT_ACTION_LOG] 
(
    [ACTION_UUID] ASC,
    [STATUS] ASC
)

CREATE NONCLUSTERED INDEX [missing_index_11438530_11438529_HTT_ACTION_LOG] ON [dbo].[HTT_ACTION_LOG] 
(
    [TRANSITION_UUID] ASC,
    [ACTION_TYPE] ASC
)
INCLUDE ( [ACTION_NAME])

CREATE NONCLUSTERED INDEX [missing_index_7207590_7207589_HTT_ACTION_LOG] ON [dbo].[HTT_ACTION_LOG] 
(
    [STATUS] ASC
)
INCLUDE ( [CREATED],
[PENDING_SINCE],
[ACTION_NAME])

CREATE NONCLUSTERED INDEX [missing_index_8535421_8535420_HTT_ACTION_LOG] ON [dbo].[HTT_ACTION_LOG] 
(
    [TRANSITION_UUID] ASC
)
INCLUDE ( [ACTION_UUID],
[STATUS])

ALTER TABLE [dbo].[HTT_ACTION_LOG] SET (LOCK_ESCALATION = AUTO)

ALTER TABLE [dbo].[HTT_ACTION_LOG]  WITH CHECK ADD  CONSTRAINT [FK_HTT_ACTION_LOG_1] FOREIGN KEY([TRANSITION_UUID])
REFERENCES [dbo].[HTT_TRANSITION_LOG] ([TRANSITION_UUID])

ALTER TABLE [dbo].[HTT_ACTION_LOG] CHECK CONSTRAINT [FK_HTT_ACTION_LOG_1]

ALTER TABLE [dbo].[HTT_ACTION_LOG] ADD  DEFAULT ('OPEN') FOR [STATUS]

ALTER TABLE [dbo].[HTT_ACTION_LOG] ADD  DEFAULT (getutcdate()) FOR [CREATED]

ALTER TABLE [dbo].[HTT_ACTION_LOG] ADD  DEFAULT ((0)) FOR [ERROR_OK]

উত্তর:


13

এই দুটি প্রশ্নের জন্য অনুকূল সূচক সূচকের বিদ্যমান সংজ্ঞা থেকে খুব বেশি দূরে নয় IK_HTT_ACTION_LOG_1( নীচের উন্নত সূচকে ACTION_UUIDএকটি হিসাবে যুক্ত করুন INCLUDE):

CREATE INDEX nc1
ON dbo.HTT_ACTION_LOG
(
    TRANSITION_UUID,
    STATUS,
    ACTION_SEQ
);

প্রথম ক্যোয়ারীটি হ'ল:

UPDATE dbo.HTT_ACTION_LOG
SET [STATUS] = 'ABORTED', 
    CLOSED = GETUTCDATE()
WHERE
    TRANSITION_UUID = '{F53ADDDA-E46B-4726-66D8-D7B640B66597}'
    AND [STATUS] = 'OPEN';

নিম্নলিখিত কার্যনির্বাহী পরিকল্পনা প্রদান:

আপডেট 1

দ্বিতীয় ক্যোয়ারীটি এভাবে প্রকাশ করা যেতে পারে:

UPDATE ToUpdate 
SET [STATUS] = 'RUNNING {36082BCD-EB52-4358-E3D3-4D96FD5B9F0F} 1360094342'
FROM
(
    SELECT TOP (1)
        hal.[STATUS]
    FROM dbo.HTT_ACTION_LOG AS hal
    WHERE
        hal.transition_uuid = '{F53ADDDA-E46B-4726-66D8-D7B640B66597}'
        AND hal.[STATUS] = 'OPEN'
    ORDER BY
        hal.ACTION_SEQ ASC
) AS ToUpdate;

এই কার্যকরকরণ পরিকল্পনা প্রদান:

আপডেট 2

উভয় ক্যোয়ারী এখন একই ক্রমে একই সংস্থানগুলিতে অ্যাক্সেস করতে পারে, যখন পরিকল্পনার পঠনপাশে অনেক কম সারি লক করে রাখা হয়। UPDLOCKনতুন সূচকটি পড়ার সময় এক্সিকিউশন ইঞ্জিনটি স্বয়ংক্রিয়ভাবে গ্রহণ করবে , আপনি যে সিরিয়ালাইজেশনটি সন্ধান করছেন তা সরবরাহ করবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.