কেন ইউপিডলক SELECTs হ্যাং (লক) করতে পারে?


13

আমি এসকিউএল সার্ভারে একটি নির্বাচন পেয়েছি যা পুরো টেবিলটিকে লক করে দেয়।

এখানে সেটআপ স্ক্রিপ্ট (নিশ্চিত করুন যে আপনি কোনও কিছুই ওভাররাইট না করেছেন)

USE [master]
GO

IF EXISTS(SELECT 1 FROM sys.databases d WHERE d.name = 'LockingTestDB')
DROP DATABASE LockingTestDB
GO

CREATE DATABASE LockingTestDB
GO

USE [LockingTestDB]
GO
IF EXISTS(SELECT 1 FROM sys.tables t WHERE t.name = 'LockingTestTable')
  DROP TABLE LockingTestTable
GO

CREATE TABLE LockingTestTable (
  Id int IDENTITY(1, 1),
  Name varchar(100),
  PRIMARY KEY CLUSTERED (Id)
)
GO

INSERT INTO LockingTestTable(Name) VALUES ('1')
INSERT INTO LockingTestTable(Name) VALUES ('2')
GO

একটি নতুন ক্যোয়ারী উইন্ডোটি খুলুন এবং নিম্নলিখিত লেনদেনটি চালান (যার এতে অপেক্ষা রয়েছে):

USE [LockingTestDB]
GO

BEGIN TRANSACTION
  SELECT * FROM LockingTestTable t WITH (UPDLOCK, ROWLOCK) WHERE t.Name = '1'
  WAITFOR DELAY '00:01:00'

COMMIT TRANSACTION
--ROLLBACK
GO

USE [master]
GO

এবং অন্য একটি যা চলবে (তারা একই সাথে চালাবেন তা নিশ্চিত করুন):

USE [LockingTestDB]
GO

SELECT * FROM LockingTestTable t WITH (UPDLOCK, ROWLOCK) WHERE t.Name = '2'

USE [master]
GO

আপনি লক্ষ্য করবেন যে দ্বিতীয় ক্যোয়ারী প্রথম দ্বারা অবরুদ্ধ হয়ে যাবে। প্রথম জিজ্ঞাসা বন্ধ করুন এবং রোলব্যাকটি কার্যকর করুন এবং দ্বিতীয়টি সম্পূর্ণ হবে।

এটি কেন ঘটছে?

PS: নামের সাথে একটি ক্লাস্টারবিহীন সূচক (সম্পূর্ণ কভারেজ সহ) যুক্ত করা এটি ঠিক করবে:

USE [LockingTestDB]
GO

CREATE NONCLUSTERED INDEX [IX_Name] ON [dbo].[LockingTestTable] 
(
  [Name] ASC
)
INCLUDE ( [Id]) WITH (STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

আবার কেন?

উত্তর:


19

হিসাবে বই অনলাইন মধ্যে নথিভুক্ত , UPDLOCKআপডেট কেশ নেয় ও সেগুলিকে লেনদেন শেষে ঝুলিতে।

লক হওয়ার জন্য সারি (গুলি) সনাক্ত করার জন্য একটি সূচক ছাড়া, সমস্ত পরীক্ষিত সারিগুলি লক হয়ে যায় এবং লেনদেন শেষ না হওয়া অবধি যোগ্য সারিগুলির লকগুলি রাখা হয়।

প্রথম লেনদেনের সারিতে একটি আপডেট লক থাকে যেখানে নাম = 1 থাকে যখন দ্বিতীয় লেনদেনটি একই সারিতে একটি আপডেট লক অর্জন করার চেষ্টা করা হয় (সেই সারির জন্য নাম = 2 পরীক্ষা করার জন্য) তখন তা অবরুদ্ধ থাকে।

একটি সূচকের সাথে, এসকিউএল সার্ভার কেবলমাত্র সেই সারিগুলিকে দ্রুত সনাক্ত এবং লক করতে পারে যা যোগ্যতা অর্জন করে, তাই কোনও বিরোধ নেই।

লক করার ইঙ্গিতটির কারণটি যাচাই করার জন্য এবং উপযুক্ত সূচকগুলি উপস্থিত রয়েছে তা নিশ্চিত করার জন্য আপনার একটি যোগ্য ডাটাবেস পেশাদারের সাথে কোডটি পর্যালোচনা করা উচিত।

সম্পর্কিত তথ্য: প্রতিশ্রুতিবদ্ধ স্ন্যাপশট বিচ্ছিন্নকরণের অধীনে ডেটা পরিবর্তনসমূহ

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