মুছে ফেলার / সন্নিবেশ করানোর জন্য একই একচেটিয়াভাবে লক ক্লাস্টার কী (এনএইচবারনেট সহ) এর এসকিউএল ডেডলক


29

আমি বেশ কয়েকদিন ধরে এই অচলাবস্থার বিষয়ে কাজ করে যাচ্ছি এবং আমি যাই করুক না কেন, এটি একরকম বা অন্যভাবে স্থির থাকে।

প্রথমত, সাধারণ ভিত্তি: আমাদের অনেকের মধ্যে একটি সম্পর্কে ভিজিটআইটেমের সাথে ভিজিট রয়েছে।

ভিজিটআইটেমগুলি সম্পর্কিত তথ্য:

CREATE TABLE [BAR].[VisitItems] (
    [Id]                INT             IDENTITY (1, 1) NOT NULL,
    [VisitType]         INT             NOT NULL,
    [FeeRateType]       INT             NOT NULL,
    [Amount]            DECIMAL (18, 2) NOT NULL,
    [GST]               DECIMAL (18, 2) NOT NULL,
    [Quantity]          INT             NOT NULL,
    [Total]             DECIMAL (18, 2) NOT NULL,
    [ServiceFeeType]    INT   NOT NULL,
    [ServiceText]       NVARCHAR (200)  NULL,
    [InvoicingProviderId] INT   NULL,
    [FeeItemId]        INT             NOT NULL,
    [VisitId]          INT             NULL,
    [IsDefault] BIT NOT NULL DEFAULT 0, 
    [SourceVisitItemId] INT NULL, 
    [OverrideCode] INT NOT NULL DEFAULT 0, 
    [InvoiceToCentre] BIT NOT NULL DEFAULT 0, 
    [IsSurchargeItem] BIT NOT NULL DEFAULT 0, 
    CONSTRAINT [PK_BAR.VisitItems] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_BAR.VisitItems_BAR.FeeItems_FeeItem_Id] FOREIGN KEY ([FeeItemId]) REFERENCES [BAR].[FeeItems] ([Id]),
    CONSTRAINT [FK_BAR.VisitItems_BAR.Visits_Visit_Id] FOREIGN KEY ([VisitId]) REFERENCES [BAR].[Visits] ([Id]), 
    CONSTRAINT [FK_BAR.VisitItems_BAR.VisitTypes] FOREIGN KEY ([VisitType]) REFERENCES [BAR].[VisitTypes]([Id]), 
    CONSTRAINT [FK_BAR.VisitItems_BAR.FeeRateTypes] FOREIGN KEY ([FeeRateType]) REFERENCES [BAR].[FeeRateTypes]([Id]),
    CONSTRAINT [FK_BAR.VisitItems_CMN.Users_Id] FOREIGN KEY (InvoicingProviderId) REFERENCES [CMN].[Users] ([Id]),
    CONSTRAINT [FK_BAR.VisitItems_BAR.VisitItems_SourceVisitItem_Id] FOREIGN KEY ([SourceVisitItemId]) REFERENCES [BAR].[VisitItems]([Id]),
    CONSTRAINT [CK_SourceVisitItemId_Not_Equal_Id] CHECK ([SourceVisitItemId] <> [Id]),
    CONSTRAINT [FK_BAR.VisitItems_BAR.OverrideCodes] FOREIGN KEY ([OverrideCode]) REFERENCES [BAR].[OverrideCodes]([Id]),
    CONSTRAINT [FK_BAR.VisitItems_BAR.ServiceFeeTypes] FOREIGN KEY ([ServiceFeeType]) REFERENCES [BAR].[ServiceFeeTypes]([Id])
)

CREATE NONCLUSTERED INDEX [IX_FeeItem_Id]
    ON [BAR].[VisitItems]([FeeItemId] ASC)

CREATE NONCLUSTERED INDEX [IX_Visit_Id]
    ON [BAR].[VisitItems]([VisitId] ASC)

তথ্য দেখুন:

CREATE TABLE [BAR].[Visits] (
    [Id]                     INT            IDENTITY (1, 1) NOT NULL,
    [VisitType]              INT            NOT NULL,
    [DateOfService]          DATETIMEOFFSET  NOT NULL,
    [InvoiceAnnotation]      NVARCHAR(255)  NULL ,
    [PatientId]              INT            NOT NULL,
    [UserId]                 INT            NULL,
    [WorkAreaId]             INT            NOT NULL, 
    [DefaultItemOverride] BIT NOT NULL DEFAULT 0, 
    [DidNotWaitAdjustmentId] INT NULL, 
    [AppointmentId] INT NULL, 
    CONSTRAINT [PK_BAR.Visits] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_BAR.Visits_CMN.Patients] FOREIGN KEY ([PatientId]) REFERENCES [CMN].[Patients] ([Id]) ON DELETE CASCADE,
    CONSTRAINT [FK_BAR.Visits_CMN.Users] FOREIGN KEY ([UserId]) REFERENCES [CMN].[Users] ([Id]),
    CONSTRAINT [FK_BAR.Visits_CMN.WorkAreas_WorkAreaId] FOREIGN KEY ([WorkAreaId]) REFERENCES [CMN].[WorkAreas] ([Id]), 
    CONSTRAINT [FK_BAR.Visits_BAR.VisitTypes] FOREIGN KEY ([VisitType]) REFERENCES [BAR].[VisitTypes]([Id]),
    CONSTRAINT [FK_BAR.Visits_BAR.Adjustments] FOREIGN KEY ([DidNotWaitAdjustmentId]) REFERENCES [BAR].[Adjustments]([Id]), 
);

CREATE NONCLUSTERED INDEX [IX_Visits_PatientId]
    ON [BAR].[Visits]([PatientId] ASC);

CREATE NONCLUSTERED INDEX [IX_Visits_UserId]
    ON [BAR].[Visits]([UserId] ASC);

CREATE NONCLUSTERED INDEX [IX_Visits_WorkAreaId]
    ON [BAR].[Visits]([WorkAreaId]);

একাধিক ব্যবহারকারী নিম্নলিখিত পদ্ধতিতে একই সাথে ভিজিটআইটেম সারণি আপডেট করতে চান:

একটি পৃথক ওয়েব অনুরোধ ভিজিটআইটেম সহ একটি দর্শন তৈরি করবে (সাধারণত 1)। তারপরে (সমস্যার অনুরোধ):

  1. ওয়েব অনুরোধ আসে, এনহাইবারনেট অধিবেশন খোলে, এনহাইবারনেট লেনদেন শুরু হয় (READ_COMMITTED_SNAPSHOT এর সাথে পুনরাবৃত্তিযোগ্য রিড ব্যবহার করে)।
  2. ভিজিটআইডির মাধ্যমে প্রদত্ত ভিজিটের জন্য সমস্ত ভিজিট আইটেম পড়ুন ।
  3. কোডগুলি মূল্যায়ন করে যদি আইটেমগুলি এখনও প্রাসঙ্গিক হয় বা আমাদের যদি জটিল বিধিগুলি ব্যবহার করে নতুন প্রয়োজন হয় (এতটা দীর্ঘ চলমান, যেমন 40 মিমি)।
  4. কোডটি খুঁজে পেয়েছে যে 1 টি আইটেম যুক্ত করা দরকার, এটি এনএইচবারনেট ভিজিট ব্যবহার করে যুক্ত করুন is ভিজিটআইটেমস.এড করুন (..)
  5. কোড শনাক্ত করে যে একটি আইটেম মুছে ফেলা দরকার (আমরা কেবল এটি যুক্ত করি নি), এনএইচবারনেট ভিজিট ব্যবহার করে এটিকে সরিয়ে দেয় isভিজিটআইটেমস em সরান (আইটেম)।
  6. কোড লেনদেন করে

একটি সরঞ্জামের সাহায্যে আমি 12 একযোগে অনুরোধগুলি অনুকরণ করি যা ভবিষ্যতের উত্পাদন পরিবেশে সম্ভবত হওয়ার সম্ভাবনা।

[সম্পাদনা] অনুরোধ করার পরে, এটিকে সংক্ষিপ্ত রাখতে আমি এখানে যুক্ত করেছিলাম এমন অনেক তদন্তের বিবরণ সরিয়ে নিয়েছি।

প্রচুর গবেষণার পরে পরবর্তী পদক্ষেপটি ছিল যেখানে আমি কীভাবে ক্লজটিতে ব্যবহৃত একটিতে (যেমন প্রাথমিক কী, যেটি মুছে ফেলার জন্য ব্যবহার করা হয়) আলাদাভাবে সূচকে কীভাবে ইঙ্গিতটি লক করতে পারি তার একটি উপায় চিন্তা করা, তাই আমি আমার লক স্টেটমেন্টটি এতে পরিবর্তন করেছি :

var items = (List<VisitItem>)_session.CreateSQLQuery(@"SELECT * FROM BAR.VisitItems WITH (XLOCK, INDEX([PK_BAR.VisitItems]))
        WHERE VisitId = :visitId")
        .AddEntity(typeof(VisitItem))
        .SetParameter("visitId", qi.Visit.Id)
        .List<VisitItem>();

এটি ফ্রিকোয়েন্সিতে অচলাবস্থা সামান্য হ্রাস করেছে, কিন্তু তারা এখনও ঘটছে। এখানেই আমি হারিয়ে যেতে শুরু করি:

তিনটি একচেটিয়া তালা?

<deadlock-list>
  <deadlock victim="process3f71e64e8">
    <process-list>
      <process id="process3f71e64e8" taskpriority="0" logused="0" waitresource="KEY: 5:72057594071744512 (a5e1814e40ba)" waittime="3812" ownerId="8004520" transactionname="user_transaction" lasttranstarted="2015-12-14T10:24:58.010" XDES="0x3f7cb43b0" lockMode="X" schedulerid="1" kpid="15788" status="suspended" spid="63" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2015-12-14T10:24:58.013" lastbatchcompleted="2015-12-14T10:24:58.013" lastattention="1900-01-01T00:00:00.013" clientapp=".Net SqlClient Data Provider" hostname="ABC" hostpid="10016" loginname="bsapp" isolationlevel="repeatable read (3)" xactid="8004520" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
        <executionStack>
          <frame procname="adhoc" line="1" stmtstart="18" stmtend="254" sqlhandle="0x0200000024a9e43033ef90bb631938f939038627209baafb0000000000000000000000000000000000000000">
            unknown
          </frame>
          <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
            unknown
          </frame>
        </executionStack>
        <inputbuf>
          (@p0 int)SELECT * FROM BAR.VisitItems WITH (XLOCK, INDEX([PK_BAR.VisitItems]))
          WHERE VisitId = @p0
        </inputbuf>
      </process>
      <process id="process4105af468" taskpriority="0" logused="1824" waitresource="KEY: 5:72057594071744512 (8194443284a0)" waittime="3792" ownerId="8004519" transactionname="user_transaction" lasttranstarted="2015-12-14T10:24:58.010" XDES="0x3f02ea3b0" lockMode="S" schedulerid="8" kpid="15116" status="suspended" spid="65" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2015-12-14T10:24:58.033" lastbatchcompleted="2015-12-14T10:24:58.033" lastattention="1900-01-01T00:00:00.033" clientapp=".Net SqlClient Data Provider" hostname="ABC" hostpid="10016" loginname="bsapp" isolationlevel="repeatable read (3)" xactid="8004519" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
        <executionStack>
          <frame procname="adhoc" line="1" stmtstart="18" stmtend="98" sqlhandle="0x0200000075abb0074bade5aa57b8357410941428df4d54130000000000000000000000000000000000000000">
            unknown
          </frame>
          <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
            unknown
          </frame>
        </executionStack>
        <inputbuf>
          (@p0 int)DELETE FROM BAR.VisitItems WHERE Id = @p0
        </inputbuf>
      </process>
    </process-list>
    <resource-list>
      <keylock hobtid="72057594071744512" dbid="5" objectname="BAR.VisitItems" indexname="PK_BAR.VisitItems" id="lock449e27500" mode="X" associatedObjectId="72057594071744512">
        <owner-list>
          <owner id="process4105af468" mode="X"/>
        </owner-list>
        <waiter-list>
          <waiter id="process3f71e64e8" mode="X" requestType="wait"/>
        </waiter-list>
      </keylock>
      <keylock hobtid="72057594071744512" dbid="5" objectname="BAR.VisitItems" indexname="PK_BAR.VisitItems" id="lock46a525080" mode="X" associatedObjectId="72057594071744512">
        <owner-list>
          <owner id="process3f71e64e8" mode="X"/>
        </owner-list>
        <waiter-list>
          <waiter id="process4105af468" mode="S" requestType="wait"/>
        </waiter-list>
      </keylock>
    </resource-list>
  </deadlock>
</deadlock-list>

ফলাফলের সংখ্যার প্রশ্নের একটি চিহ্ন এটির মতো দেখাচ্ছে।
[সম্পাদনা] হু। কি এক সপ্তাহ। আমি এখন প্রাসঙ্গিক বিবৃতিটির অচিহ্নিত ট্রেস দিয়ে ট্রেস আপডেট করেছি যা আমি মনে করি যে অচলাবস্থার দিকে নিয়ে যায়।

exec sp_executesql N'SELECT * FROM BAR.VisitItems WITH (XLOCK, INDEX([PK_BAR.VisitItems]))
                WHERE VisitId = @p0',N'@p0 int',@p0=3826
go
exec sp_executesql N'SELECT visititems0_.VisitId as VisitId1_, visititems0_.Id as Id1_, visititems0_.Id as Id37_0_, visititems0_.VisitType as VisitType37_0_, visititems0_.FeeItemId as FeeItemId37_0_, visititems0_.FeeRateType as FeeRateT4_37_0_, visititems0_.Amount as Amount37_0_, visititems0_.GST as GST37_0_, visititems0_.Quantity as Quantity37_0_, visititems0_.Total as Total37_0_, visititems0_.ServiceFeeType as ServiceF9_37_0_, visititems0_.ServiceText as Service10_37_0_, visititems0_.InvoiceToCentre as Invoice11_37_0_, visititems0_.IsDefault as IsDefault37_0_, visititems0_.OverrideCode as Overrid13_37_0_, visititems0_.IsSurchargeItem as IsSurch14_37_0_, visititems0_.VisitId as VisitId37_0_, visititems0_.InvoicingProviderId as Invoici16_37_0_, visititems0_.SourceVisitItemId as SourceV17_37_0_ FROM BAR.VisitItems visititems0_ WHERE visititems0_.VisitId=@p0',N'@p0 int',@p0=3826
go
exec sp_executesql N'INSERT INTO BAR.VisitItems (VisitType, FeeItemId, FeeRateType, Amount, GST, Quantity, Total, ServiceFeeType, ServiceText, InvoiceToCentre, IsDefault, OverrideCode, IsSurchargeItem, VisitId, InvoicingProviderId, SourceVisitItemId) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15); select SCOPE_IDENTITY()',N'@p0 int,@p1 int,@p2 int,@p3 decimal(28,5),@p4 decimal(28,5),@p5 int,@p6 decimal(28,5),@p7 int,@p8 nvarchar(4000),@p9 bit,@p10 bit,@p11 int,@p12 bit,@p13 int,@p14 int,@p15 int',@p0=1,@p1=452,@p2=1,@p3=0,@p4=0,@p5=1,@p6=0,@p7=1,@p8=NULL,@p9=0,@p10=1,@p11=0,@p12=0,@p13=3826,@p14=3535,@p15=NULL
go
exec sp_executesql N'UPDATE BAR.Visits SET VisitType = @p0, DateOfService = @p1, InvoiceAnnotation = @p2, DefaultItemOverride = @p3, AppointmentId = @p4, ReferralRequired = @p5, ReferralCarePlan = @p6, UserId = @p7, PatientId = @p8, WorkAreaId = @p9, DidNotWaitAdjustmentId = @p10, ReferralId = @p11 WHERE Id = @p12',N'@p0 int,@p1 datetimeoffset(7),@p2 nvarchar(4000),@p3 bit,@p4 int,@p5 bit,@p6 nvarchar(4000),@p7 int,@p8 int,@p9 int,@p10 int,@p11 int,@p12 int',@p0=1,@p1='2016-01-22 12:37:06.8915296 +08:00',@p2=NULL,@p3=0,@p4=NULL,@p5=0,@p6=NULL,@p7=3535,@p8=4246,@p9=2741,@p10=NULL,@p11=NULL,@p12=3826
go
exec sp_executesql N'DELETE FROM BAR.VisitItems WHERE Id = @p0',N'@p0 int',@p0=7919
go

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

আমি মনে করি যে একই টেবিলে একাধিক কী নিয়ে গেলে লকগুলি কীভাবে কাজ করে সে সম্পর্কে আমার এখানে কিছু গভীর বোঝার অভাব রয়েছে।

এখানে আমি চেষ্টা করেছি এমন কয়েকটি জিনিস এবং তার প্রভাব:

  • লক স্টেটমেন্টে আইএক্স_ভিসিট_আইডিতে আরও একটি সূচক ইঙ্গিত যুক্ত হয়েছে। পরিবর্তন নেই
  • IX_Visit_Id (ভিজিট আইটেম কলামের আইডি) এ একটি দ্বিতীয় কলাম যুক্ত করা হয়েছে; বহুল প্রচারিত, তবে যাইহোক চেষ্টা করা। পরিবর্তন নেই
  • প্রতিশ্রুতিবদ্ধ (আমাদের প্রকল্পে ডিফল্ট) পড়তে বিচ্ছিন্নতা স্তরটি ফিরে ফিরে গেছে, অচলাবস্থা এখনও চলছে
  • বিচ্ছিন্নতা স্তরটি ক্রমিকায়িত করতে পরিবর্তিত হয়েছে। ডেডলকগুলি এখনও ঘটছে, তবে আরও খারাপ (বিভিন্ন গ্রাফ)। আমি সত্যিই যাইহোক, এটি করতে চাই না।
  • টেবিল লক নিলে তাদের চলে যায় (স্পষ্টতই), কিন্তু কে এটি করতে চায়?
  • একটি হতাশাবাদী অ্যাপ্লিকেশন লক নেওয়া (sp_getapplock ব্যবহার করে) কাজ করে, তবে এটি টেবিল লকের মতো একই জিনিস, এটি করতে চান না।
  • এক্সএলডকে ইঙ্গিতটিতে READPAST ইঙ্গিত যুক্ত করা কোনও তাত্পর্যপূর্ণ হয়নি
  • আমি সূচক এবং পিকে পেজলক বন্ধ করেছি, কোনও পার্থক্য নেই
  • আমি এক্সলোক ইঙ্গিতটিতে রাওলোক ইঙ্গিত যুক্ত করেছি, কোনও পার্থক্য নেই

এনএইচবারনেট সম্পর্কিত কয়েকটি পক্ষের নোট: এটি যেভাবে ব্যবহৃত হয়েছে এবং আমি বুঝতে পারি এটি কাজ করে তা হ'ল এসকিএল স্টেটমেন্টগুলিকে ক্যাশ করে যতক্ষণ না এটি সত্যিকার অর্থে এটি কার্যকর করার প্রয়োজন খুঁজে পাওয়া যায়, যদি না আপনি ফ্লাশকে কল করেন, যা আমরা না করার চেষ্টা করছি। সুতরাং বেশিরভাগ বিবৃতি (যেমন: ভিজিটআইটেমগুলির অলস লোডের সমষ্টিগত তালিকা => ভিজিট.ভিট আইটেমস) কেবলমাত্র যখন প্রয়োজন হয় তখন সম্পাদন করা হয়। আমার লেনদেনের আসল আপডেট এবং মুছে ফেলার বিবরণীর বেশিরভাগই লেনদেনটি করা হলে শেষ হয়ে যায় (উপরের স্ক্যুএল ট্রেস থেকে প্রমাণিত হয়)। মৃত্যুদণ্ড কার্যকর করার আদেশের উপর আমার সত্যিই কোনও নিয়ন্ত্রণ নেই; এনহাইবারনেট সিদ্ধান্ত নেয় কখন কী করা উচিত। আমার প্রাথমিক লক স্টেটমেন্টটি সত্যই কেবল একটি কাজের জায়গা।

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

তবে ব্যাপারটা ঠিক নয়, তাই না? আমার কাছে ইতিমধ্যে কী কী লক আছে? এটি আবার লোড করা কি পরিবর্তন হবে না?

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

এর থেকে আরও কীভাবে যোগাযোগ করা যায় সে সম্পর্কে কারও ধারণা আছে? আমি স্মার্ট উপায়ে এটিকে ঘুরে দেখার চেষ্টা করতে পারি যে কোনও কিছুই (কোনও টেবিল লক ইত্যাদি নেই)? এছাড়াও, আমি শিখতে চাই কেন একই ট্রিপলটিতে এই ট্রিপল-এক্স লকটি সম্ভব। আমি বুঝতে পারছি না।

ধাঁধাটি সমাধান করার জন্য আরও যদি কোনও তথ্যের প্রয়োজন হয় তবে দয়া করে আমাকে জানান।

[সম্পাদনা] আমি জড়িত দুটি টেবিলের জন্য প্রশ্নটি ডিডিএল দিয়ে আপডেট করেছি।

এছাড়াও আমাকে প্রত্যাশার বিষয়ে স্পষ্টতা জিজ্ঞাসা করা হয়েছিল: হ্যাঁ, এখানে কয়েকটি অচলাবস্থা রয়েছে এবং ঠিক আছে, আমরা কেবল পুনরায় চেষ্টা করব বা ব্যবহারকারীর পুনরায় জমা দেওয়ার জন্য (সাধারণত কথা বলার) করব। তবে 12 একযোগে ব্যবহারকারীর সাথে বর্তমান ফ্রিকোয়েন্সিতে, আমি আশা করব যে সেখানে প্রতি কয়েক ঘন্টা কেবলমাত্র একজন থাকবে। বর্তমানে তারা প্রতি মিনিটে একাধিকবার পপ আপ করে।

এগুলি ছাড়াও, আমি ট্রান্সকাউন্ট = 2 সম্পর্কে আরও কিছু তথ্য পেয়েছি, যা নেস্টেড লেনদেনের ক্ষেত্রে একটি সমস্যা নির্দেশ করতে পারে, যা আমরা সত্যিই ব্যবহার করছি না। আমি এটিও তদন্ত করব এবং ফলাফলগুলি এখানে ডকুমেন্ট করব।


2
নির্বাচন করুন * ব্যবহার করবেন না। এটি আপনার সমস্যাগুলির ক্ষেত্রে অবদান রাখার কারণ হতে পারে। দেখুন stackoverflow.com/questions/3639861/...
JamieSee

এছাড়াও, SELECT OBJECT_NAME(objectid, dbid) AS objectname, * FROM sys.dm_exec_sql_text(0x0200000024a9e43033ef90bb631938f939038627209baafb0000000000000000000000000000000000000000)প্রকৃতপক্ষে কী সম্পাদিত হচ্ছে তা নির্ধারণ করতে প্রতিটি এক্সিকিউশনস্ট্যাক ফ্রেমে স্ক্যালহ্যান্ডেলের জন্য চালান ।
জেমিসি

আপনি সম্ভবত একটি হ্যাশ সংঘর্ষে দৌড়াচ্ছেন? dba.stackexchange.com/questions/80088/insert-only-deadlocks/…
জনবয়

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

আপনার সাহায্য করতে পারে এমন আরও ডেডলক বিশদ পেতে আপনি এই প্রশ্নের আমার পাওয়ারশেল স্ক্রিপ্টের উত্তরটি ব্যবহার করতে পারেন। বিশেষত, এটি আপনার "অজানা" স্ট্যাক ফ্রেমের জন্য এসকিউএল বিবৃতি তথ্য পুনরুদ্ধার করবে। dba.stackexchange.com/questions/28996/…
জ্যামিএসআই

উত্তর:


2

আমি এই সম্পর্কে কয়েকটি মন্তব্য করেছি, তবে আমি নিশ্চিত নই যে আপনি পুনরাবৃত্তিযোগ্য পড়ুন লেনদেনের বিচ্ছিন্নতা স্তরটি রিড কমিটেড স্ন্যাপশটের সাথে একত্রিত করার সময় আপনি পছন্দসই ফলাফল পেয়ে যাচ্ছেন।

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

আপনি যা করার চেষ্টা করছেন তা হ'ল আপনার ডিবি টিআইএল পুনরাবৃত্তযোগ্য পড়তে পারা, তবে স্ন্যাপশট টিআইএল স্পষ্টভাবে একটি সেট লেনদেনের বিচ্ছিন্নতা স্তরের স্টেটমেন্টের সাথে ব্যবহারের জন্য লেনদেন সেট করুন। তথ্যসূত্র: https://msdn.microsoft.com/en-us/library/ms173763.aspx যদি তা হয় তবে আমার মনে হয় আপনার অবশ্যই কিছু ভুল আছে। আমি এন হাইবারনেটের সাথে পরিচিত নই, তবে মনে হচ্ছে এখানে একটি রেফারেন্স রয়েছে: http://www.anujvarma.com/fluent-nhibernate-setting-database-transaction-isolation-level/

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


2

আমার বেশ কয়েকটা চিন্তাভাবনা আছে। প্রথমত, ডেডলকগুলি এড়ানোর সহজ উপায় হ'ল সর্বদা একই ক্রমে লক নেওয়া। এর অর্থ সুস্পষ্ট লেনদেন ব্যবহার করে বিভিন্ন কোডের একই ক্রমে অবজেক্টগুলিতে অ্যাক্সেস করা উচিত তবে সুস্পষ্ট লেনদেনে কী দ্বারা স্বতন্ত্রভাবে সারিগুলিতে অ্যাক্সেস করাও সেই কীটিতে বাছাই করা উচিত। বাছাই করার চেষ্টা করুনVisit.VisitItems আগে এটির পিকেAdd বা Deleteযদি না এটির একটি বিশাল সংগ্রহ না হয় যেখানে আমি সাজিয়ে থাকি SELECT

এখানে বাছাই করা সম্ভবত আপনার সমস্যা নয়। আমি অনুমান করছি যে VisitItemIDকোনও VisitIDথ্রেড একটি দেওয়া জন্য সমস্ত এসগুলিতে ভাগ করা লকগুলি ধরবে এবং থ্রেড এ এর DELETEসম্পূর্ণ না হওয়া পর্যন্ত থ্রেড বি এর ভাগ করা লকটি প্রকাশ না করবে যা এটি DELETEসম্পূর্ণ না হওয়া অবধি না । অ্যাপ লকগুলি এখানে কাজ করবে এবং টেবিল লকগুলির মতো খারাপ নয় কারণ তারা কেবল পদ্ধতি দ্বারা অবরুদ্ধ করে এবং অন্যান্য SELECTগুলি ঠিক কাজ করবে work আপনি Visitপ্রদত্তের জন্য টেবিলে একচেটিয়া লকও নিতে পারেন VisitIDতবে এটি সম্ভবত সম্ভাব্য ওভারকিল।

আমি আপনার হার্ড মুছাটিকে নরম মোছার UPDATE ... SET IsDeleted = 1পরিবর্তে ( ব্যবহারের পরিবর্তে DELETE) পরিণত করার এবং এই রেকর্ডগুলি পরে প্রচুর পরিমাণে পরিষ্কার করার জন্য স্পষ্ট লেনদেন ব্যবহার না করে এমন কোনও ক্লিনআপ জব ব্যবহার করার পরামর্শ দেব । এই মুছে ফেলা সারিগুলি অগ্রাহ্য করার জন্য অবশ্যই অন্য কোডের পুনঃনির্ধারণের প্রয়োজন হবে তবে সুস্পষ্ট লেনদেনে DELETEঅন্তর্ভুক্ত গুলি পরিচালনার জন্য আমার পছন্দসই পদ্ধতি SELECT

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


1

ভিজিট আইটেমে কোনও পরিবর্তন করার আগে আপনি কি ভিজিট আপডেটটি সরানোর চেষ্টা করেছেন? এই এক্স-লকটি "শিশু" সারিগুলি রক্ষা করবে।

অর্জিত পুরো তালা তৈরি করা ট্রেস (এবং মানব-পঠনযোগ্য রূপান্তরকরণ) অনেক কাজ কিন্তু ক্রমটি আরও স্পষ্টভাবে প্রদর্শিত হতে পারে।


-1

কোনও টেবিল আটকা পড়েছে কেন আপনার যদি কোনও ধারণা না থাকে তবে কখনও কখনও ট্রান আটকে থাকে

SEX XACT_ABORT চালু -> এটি ট্রান আটকে যাওয়ার কারণে ত্রুটিগুলির যত্ন নেওয়া উচিত BEGIN TRAN TRAN_NAME --CODE টেবিলটি অ্যাক্সেস করছে - কমিট ট্রান ট্রান_NAME

https://stackoverflow.com/questions/2277254/how-to-set-xact-abort-within-ado-net


-1

রিড কমিটিকেটেড স্নাপশট চালু করার অর্থ হ'ল রিড সংহত বিচ্ছিন্নতা লেভেলে চলমান প্রতিটি একক লেনদেন রিড কমিটিকেটেড স্নাপশট হিসাবে কাজ করবে।

এর অর্থ হ'ল পাঠকরা লেখককে ব্লক করবেন না এবং লেখকরা পাঠকদের অবরুদ্ধ করবেন না।

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

আপনি যদি আপনার ডেডলক গ্রাফটি একবার দেখে থাকেন তবে আপনি একটি "এস" লক অর্জিত দেখতে পাবেন। আমি মনে করি এটি দ্বিতীয় পয়েন্টের লক -> "ভিজিটআইডের দ্বারা প্রদত্ত ভিজিটের জন্য সমস্ত ভিজিট আইটেমগুলি পড়ুন।"

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