এসকিউএল সার্ভার জবটিতে লেনদেন এবং চেষ্টা করুন


9

আমাদের এসকিউএল সার্ভার কাজের প্রতিটি ধাপে ডিএমএল অপারেশন রয়েছে। আপডেটের নিশ্চিত করার জন্য / সন্নিবেশ ক্ষেত্রে ফিরে ঘূর্ণিত করা হবে না কিছু গোলমাল, আমি এর ডেটা পরিবর্তন আবৃত করেছি প্রতিটি পদক্ষেপ মধ্যে TRY CATCHএবং TRANSACTIONব্লক:

BEGIN TRY
    BEGIN TRANSACTION

        [[INSERT/update statements]] ...

    IF @@TRANCOUNT > 0
    BEGIN
        COMMIT TRANSACTION
        PRINT 'Successful.'
    END

END TRY

BEGIN CATCH
    SELECT
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_STATE() AS ErrorState,
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_MESSAGE() AS ErrorMessage

    IF @@TRANCOUNT > 0
    BEGIN
        ROLLBACK TRANSACTION
        PRINT 'Unsuccessful.'
    END
END CATCH

এটি কী ত্রুটি (গুলি) এর ক্ষেত্রে ডেটা ম্যানিপুলেশনগুলি ফিরিয়ে আনবে তা নিশ্চিত করে? বা অন্যান্য বিবেচনার বিষয়টিও বিবেচনায় নেওয়া উচিত?

(কনফিগারেশন ইত্যাদি ব্যবহার করে) এর আরও ভাল উপায় হতে পারে?

ধন্যবাদ.

উত্তর:


7

আমি বরং ব্যতিক্রম হ্যান্ডলিং এবং নেস্টেড লেনদেনের মতো একটি প্যাটার্ন সুপারিশ করব :

create procedure [usp_my_procedure_name]
as
begin
    set nocount on;
    declare @trancount int;
    set @trancount = @@trancount;
    begin try
        if @trancount = 0
            begin transaction
        else
            save transaction usp_my_procedure_name;

        -- Do the actual work here

lbexit:
        if @trancount = 0   
            commit;
    end try
    begin catch
        declare @error int, @message varchar(4000), @xstate int;
        select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE();
        if @xstate = -1
            rollback;
        if @xstate = 1 and @trancount = 0
            rollback
        if @xstate = 1 and @trancount > 0
            rollback transaction usp_my_procedure_name;

        raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
    end catch   
end

আপত্তিজনক লেনদেনেরXACT_STATE() বিরুদ্ধে রক্ষা করতে এই প্যাটার্নটি ক্যাচ ব্লকে চেক করে :

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

আপনার কোড @@TRANCOUNTযেখানে 0 হতে পারে না সেখানে অনুসন্ধান করছে, এটি তথ্য প্রিন্ট বার্তাগুলির মিশ্রণ ব্যবহার করে এবং সাফল্যের যোগাযোগের জন্য ফলাফল ফলাফল সেট করে, এটি পুনরুদ্ধারযোগ্য ত্রুটিগুলি পরিচালনা করে না। আদর্শভাবে ব্যতিক্রমগুলি ক্লায়েন্টের কাছে এজেন্ট চাকরিতে প্রচার করা উচিত (অর্থাত্ আপনার ক্যাচটি পুনরায় উত্থাপন করা উচিত)।


আপনার সহায়ক উত্তর এবং চমত্কার ওয়েবসাইটের জন্য ধন্যবাদ! তবে আমি ভাবছি যদি এখনও আমি এই প্যাটার্নটি কোনও সাধারণ ডিএমএল স্টেটমেন্ট (কোনও সঞ্চয়স্থান নয়) দিয়ে ব্যবহার করতে পারি? এছাড়াও আমাদের কি নীচের মতো লেনদেনটি সংরক্ষণ করতে হবে? (ব্যবহারের জন্য আমার কাছে কোনও স্টোর প্রোক নেই): লেনদেন usp_my_procedure_name সংরক্ষণ করুন;
স্কাই

2

আপনার যা আছে তা আমার কাছে ভাল লাগছে। আমি আপনাকে লেনদেনটি ফিরিয়ে দেওয়ার পরে অবশ্যই তথ্য দিয়ে কিছু করার পরামর্শ দিচ্ছি যেমন এটি কোনও লগতে লিখুন।


1
আপনার জবাবের জন্য ধন্যবাদ, আপনি দয়া করে আমাকে কোনও ইঙ্গিত দিতে পারেন কীভাবে এটি লগতে লিখতে হয়?
আকাশ

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