"সন্নিবেশ অনুসন্ধান" পুরো টেবিলটি লক করার আগে "কেন লেনদেন শুরু করুন"?


11

আমি এসকিউএল সার্ভার 2005 এক্সপ্রেস ব্যবহার করছি।

একটি দৃশ্যে, আমি সঞ্চিত পদ্ধতিতে Begin Transactionএকটি INSERTবিবৃতি দেওয়ার ঠিক আগে কমান্ড যুক্ত করেছি । আমি যখন এই সঞ্চিত পদ্ধতিটি কার্যকর করি তখন এটি পুরো টেবিলটিকে লক করে দেয় এবং সমস্ত সমবর্তী সংযোগগুলি এই INSERTসমাপ্ত হওয়া অবধি হ্যাং ডিসপ্লে দেখায় ।

কেন পুরো টেবিলটি লক হয়ে যায় এবং এসকিউএল সার্ভার 2005 এক্সপ্রেসে আমি কীভাবে এই সমস্যাটি কাটিয়ে উঠতে পারি?

সম্পাদিত

অনুসন্ধান নীচের মত:

INSERT INTO <table2> SELECT * FROM <table1> WHERE table1.workCompleted = 'NO'

2
এটি পোস্টগ্র্যাস্কিলে টেবিলটি লক করে না।
স্কট মার্লো

আরও @RPK দরকার টেবিল ডিডিএল এবং সন্নিবেশগুলির একটি নমুনা সহ আমরা আপনাকে যা ঘটছে তার একটি সঠিক ব্যাখ্যা দিতে পারি। এটি ছাড়া আমরা কেবল অনুমান করছি।
মার্ক স্টোরী-স্মিথ

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

উত্তর:


25

এই উত্তরটি মূল প্রশ্নের ক্ষেত্রে সহায়ক হিসাবে প্রমাণিত হতে পারে তবে প্রাথমিকভাবে অন্যান্য পোস্টগুলিতে ভুল তথ্য সম্বোধন করা। এটি বিওএল-তে বাজে বিষয়গুলির একটি অংশকেও হাইলাইট করে।

এবং INSERT নথির জন্য যেমন বলা হয়েছে , এটি টেবিলে একটি এক্সক্লুসিভ লক অর্জন করবে। টেবিলের বিপরীতে একটি নির্বাচন করার একমাত্র উপায় হ'ল নলোকক ব্যবহার করা বা লেনদেনের বিচ্ছিন্নতা স্তর নির্ধারণ করা।

বিওএল এর সংযুক্ত বিভাগে বলা হয়েছে:

একটি INSERT বিবৃতি সর্বদা এটি পরিবর্তিত টেবিলের একটি এক্সক্লুসিভ (এক্স) লকটি অর্জন করে এবং লেনদেন শেষ না হওয়া অবধি লকটি ধরে রাখে। একটি এক্সক্লুসিভ (এক্স) লক দিয়ে, অন্য কোনও লেনদেন ডেটা পরিবর্তন করতে পারে না; পঠন অপারেশনগুলি কেবল NOLOCK ইঙ্গিত ব্যবহার করে বা নিরীক্ষণ বিচ্ছিন্নতা স্তরটি পড়তে পারে। আরও তথ্যের জন্য, ডেটাবেস ইঞ্জিনে লক করা দেখুন ।

নোট: 2014-8-27 অবধি উপরে উল্লিখিত ভুল বিবৃতিগুলি অপসারণের জন্য বিওএল আপডেট করা হয়েছে।

শুকরিয়া এই ঘটনাটি না। এটি যদি কোনও টেবিলের ভিতরে সন্নিবেশ করানো হত তবে ক্রমিকভাবে ঘটবে এবং সন্নিবেশ লেনদেন শেষ না হওয়া পর্যন্ত সমস্ত পাঠক পুরো টেবিল থেকে অবরুদ্ধ থাকবে। এটি এসকিউএল সার্ভারকে এনটিএফএস হিসাবে দক্ষ ডাটাবেস সার্ভার হিসাবে তৈরি করবে। বেশি না.

সাধারণ জ্ঞানের ধারণা এটি এমনটি হতে পারে না তবে পল র্যান্ডাল যেমন উল্লেখ করেছেন যে, " নিজেকে অনুগ্রহ করুন, কারও উপর নির্ভর করবেন না "। আপনি যদি বিওএল সহ কাউকে বিশ্বাস করতে না পারেন তবে আমি অনুমান করি আমাদের এটি প্রমাণ করতে হবে।

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

SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;

USE [master]
GO

IF EXISTS (SELECT name FROM sys.databases WHERE name = N'LockDemo')
DROP DATABASE [LockDemo]
GO

DECLARE @DataFilePath NVARCHAR(4000)
SELECT 
    @DataFilePath = SUBSTRING(physical_name, 1, CHARINDEX(N'master.mdf', LOWER(physical_name)) - 1)
FROM 
    master.sys.master_files
WHERE 
    database_id = 1 AND file_id = 1

EXEC ('
CREATE DATABASE [LockDemo] ON  PRIMARY 
( NAME = N''LockDemo'', FILENAME = N''' + @DataFilePath + N'LockDemo.mdf' + ''', SIZE = 2MB , MAXSIZE = UNLIMITED, FILEGROWTH = 2MB )
 LOG ON 
( NAME = N''LockDemo_log'', FILENAME = N''' + @DataFilePath + N'LockDemo_log.ldf' + ''', SIZE = 1MB , MAXSIZE = UNLIMITED , FILEGROWTH = 1MB )
')

GO

USE [LockDemo]
GO

SELECT DB_ID() AS DatabaseId

CREATE TABLE [dbo].[MyTable]
(
    [id] [int] IDENTITY(1,1) PRIMARY KEY CLUSTERED
    , [filler] CHAR(4030) NOT NULL DEFAULT REPLICATE('A', 4030) 
)
GO

INSERT MyTable DEFAULT VALUES;
GO 100

এমন একটি প্রোফাইলার ট্রেস সেটআপ করুন যা লকটিকে ট্র্যাক করবে: অর্জিত এবং লক করুন: প্রকাশিত ইভেন্টগুলি, পূর্ববর্তী স্ক্রিপ্ট থেকে ডেটাবেসআইডিতে ফিল্টারিং, ফাইলটির জন্য একটি পথ নির্ধারণ করে এবং ট্রেসআইডি ফিরে লক্ষ্য করে।

declare @rc int
declare @TraceID int
declare @maxfilesize BIGINT
declare @databaseid INT
DECLARE @tracefile NVARCHAR(4000)

set @maxfilesize = 5 
SET @tracefile = N'D:\Temp\LockTrace'
SET @databaseid = 9

exec @rc = sp_trace_create @TraceID output, 0, @tracefile, @maxfilesize, NULL 
if (@rc != 0) goto error

declare @on bit
set @on = 1
exec sp_trace_setevent @TraceID, 24, 32, @on
exec sp_trace_setevent @TraceID, 24, 1, @on
exec sp_trace_setevent @TraceID, 24, 57, @on
exec sp_trace_setevent @TraceID, 24, 3, @on
exec sp_trace_setevent @TraceID, 24, 51, @on
exec sp_trace_setevent @TraceID, 24, 12, @on
exec sp_trace_setevent @TraceID, 60, 32, @on
exec sp_trace_setevent @TraceID, 60, 57, @on
exec sp_trace_setevent @TraceID, 60, 3, @on
exec sp_trace_setevent @TraceID, 60, 51, @on
exec sp_trace_setevent @TraceID, 60, 12, @on
exec sp_trace_setevent @TraceID, 23, 32, @on
exec sp_trace_setevent @TraceID, 23, 1, @on
exec sp_trace_setevent @TraceID, 23, 57, @on
exec sp_trace_setevent @TraceID, 23, 3, @on
exec sp_trace_setevent @TraceID, 23, 51, @on
exec sp_trace_setevent @TraceID, 23, 12, @on

-- DatabaseId filter
exec sp_trace_setfilter @TraceID, 3, 0, 0, @databaseid

-- Set the trace status to start
exec sp_trace_setstatus @TraceID, 1

-- display trace id for future references
select TraceID=@TraceID
goto finish

error: 
select ErrorCode=@rc

finish: 
go

একটি সারি sertোকান এবং ট্রেস বন্ধ করুন:

USE LockDemo
GO
INSERT MyTable DEFAULT VALUES
GO
EXEC sp_trace_setstatus 3, 0
EXEC sp_trace_setstatus 3, 2
GO

ট্রেস ফাইলটি খুলুন এবং আপনার নিম্নলিখিতগুলি খুঁজে পাওয়া উচিত:

প্রোফাইলার উইন্ডো

নেওয়া তালার ক্রমটি হ'ল:

  1. মাই টেবেলে ইনটেন্ট-এক্সক্লুসিভ লক
  2. পৃষ্ঠায় 1: 211 তে ইন্টেন্ট-এক্সক্লুসিভ লক
  3. মান সন্নিবেশ করার জন্য ক্লাস্টারড ইনডেক্স এন্ট্রিতে রেঞ্জইনসর্ট-নুলারসোর্স
  4. কীতে এক্সক্লুসিভ লক

লকগুলি তারপরে বিপরীত ক্রমে প্রকাশ করা হয়। কোনও পর্যায়ে টেবিলে একচেটিয়া লক অর্জিত হয়নি।

তবে এটি কেবল একটি ব্যাচ সন্নিবেশ করছে! এটি সমান্তরালভাবে চলমান দুই, তিন বা ডজনের মতো নয়।

হ্যাঁ তাই হয়। এসকিউএল সার্ভার (এবং যুক্তিযুক্ত কোনও ডাটাবেস ইঞ্জিন) এর কোনও বিবরণ এবং / অথবা ব্যাচ প্রক্রিয়া করার সময় অন্যান্য ব্যাচগুলি কী চলতে পারে সে সম্পর্কে কোনও দূরদৃষ্টি নেই, তাই লক অধিগ্রহণের ক্রমটি পৃথক হয় না।

উচ্চতর বিচ্ছিন্নতা স্তরগুলি সম্পর্কে কী যেমন সিরিয়ালাইজযোগ্য?

এই নির্দিষ্ট উদাহরণের জন্য ঠিক একই লক নেওয়া হয়। আমাকে বিশ্বাস করবেন না, চেষ্টা করুন!


2
খুবই তথ্যবহুল. ভাল কাজ @ মার্ক!
jcolebrand

0

আমি বেশি টি-এসকিউএল কাজ করি না তবে ডকুমেন্টেশন পড়া থেকে ...

এটি ডিজাইনের মাধ্যমে, যেমনটি শুরু করুন শুরু করুন :

বর্তমান লেনদেনের বিচ্ছিন্নতা স্তরের সেটিংসের উপর নির্ভর করে, সংযোগ দ্বারা জারি করা লেনদেন-এসকিউএল স্টেটমেন্টকে সমর্থন করার জন্য অর্জিত অনেক সংস্থানগুলি কোনও লেনদেন দ্বারা লক করা হয় যতক্ষণ না এটি কোনও বাণিজ্য ট্রান্সমিশন বা রোলব্যাক ট্রান্সএকশন বিবৃতি দিয়ে সম্পন্ন হয়।

এবং INSERT নথির জন্য যেমন বলা হয়েছে , এটি টেবিলে একটি এক্সক্লুসিভ লক অর্জন করবে। টেবিলের বিপরীতে একটি নির্বাচন করার একমাত্র উপায় হ'ল NOLOCKলেনদেনের বিচ্ছিন্নতা স্তরটি ব্যবহার করা বা সেট করা।


4
এর আগে বিওএল-তে বরং খারাপভাবে শব্দযুক্ত বক্তব্যটি খেয়াল করেনি। রিসোর্স হায়ারার্কির মধ্যে থাকা কোনও কিছুর উপর একটি এক্সক্লুসিভ লক প্রয়োজন হবে তবে এটি অবশ্যই সারণী নয়।
মার্ক স্টোরি-স্মিথ

6
ডক্সের জন্য -1 (আপনার দোষ নয়) - স্নাপশট বিচ্ছিন্নকরণে এটি সত্য নয় তা প্রমাণ করা সহজ তাই কম্বলটি সর্বদা একটি এক্সক্লুসিভ (এক্স) লক অর্জন করে "ভুল wrong অন্যান্য বিচ্ছিন্নতা স্তর সম্পর্কে নিশ্চিত নয়।
জ্যাক বলছেন topanswers.xyz
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.