এসকিউএল সার্ভার - লেনদেন ত্রুটি ফিরে?


193

আমাদের কাছে ক্লায়েন্ট অ্যাপ রয়েছে যা একটি এসকিউএল সার্ভার ২০০৫-তে কিছু এসকিউএল চালাচ্ছে যেমন নীচের:

BEGIN TRAN;
INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
COMMIT TRAN;

এটি একটি দীর্ঘ স্ট্রিং কমান্ড দ্বারা প্রেরণ করা হয়।

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

আমি যে এপিআই এবং ভাষাটি ব্যবহার করছি সে সম্পর্কে আমি নির্দিষ্ট বিবরণ দিতে পারি তবে আমি মনে করব যে কোনও ভাষার জন্য এসকিউএল সার্ভারের একই প্রতিক্রিয়া দেখা উচিত।


উত্তর:


204

আপনি লাগাতে পারেন set xact_abort onআপনার লেনদেনের আগে নিশ্চিত SQL রোলস ত্রুটির ক্ষেত্রে স্বয়ংক্রিয়ভাবে ব্যাক করা।


1
এটি কি এমএস এসকিউএল 2 কে এবং এর চেয়ে বেশি ক্ষেত্রে কাজ করবে? এটি সবচেয়ে সহজ সমাধান বলে মনে হচ্ছে।
জোনাথান্পিপারস

1
এটি 2000, 2005 এবং 2008 এর জন্য ডক্সে উপস্থিত হয় তাই আমি হ্যাঁ ধরে নিই। আমরা এটি 2008 সালে ব্যবহার করছি

8
আমার কি এটি বন্ধ করার দরকার বা এটি প্রতি সেশনের?
মার্ক

5
@ মার্কের সুযোগটি xact_abortসংযোগ পর্যায়ে রয়েছে।
কিথ

2
@ অ্যালেক্সম্যাকমিলান ড্রপ প্রক্রিয়া বিবৃতি ইনসার্টের বিপরীতে ডাটাবেস কাঠামো পরিবর্তন করেছে, যা কেবলমাত্র ডেটা নিয়ে কাজ করে। সুতরাং এটি কোনও লেনদেনের মধ্যে মোড়ানো যায় না। আমি ওভারস্প্লিফ্লাইফিং করছি, তবে মূলত এটি এটি।
ইকোর্টসো

195

আপনি সঠিক যে পুরো লেনদেনটি আবার ঘুরিয়ে দেওয়া হবে। এটি আবার রোল করার জন্য আপনার আদেশটি জারি করা উচিত।

আপনি TRY CATCHনিম্নলিখিত হিসাবে এটি একটি ব্লক মোড়ানো করতে পারেন

BEGIN TRY
    BEGIN TRANSACTION

        INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
        INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
        INSERT INTO myTable (myColumns ...) VALUES (myValues ...);

    COMMIT TRAN -- Transaction Success!
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRAN --RollBack in case of Error

    -- you can Raise ERROR with RAISEERROR() Statement including the details of the exception
    RAISERROR(ERROR_MESSAGE(), ERROR_SEVERITY(), 1)
END CATCH

2
আমি ডাইংক্যাকটাসের সমাধানটি আরও ভাল পছন্দ করি, তার পরিবর্তনের জন্য কোডের 1 লাইন। আপনার যদি কোনও কারণে ভাল হয় (বা আরও নির্ভরযোগ্য) আমাকে জানান।
জোনাথনপ্পের্স 17:59

13
চেষ্টা ধরা আপনাকে ত্রুটি ক্যাপচার (এবং সম্ভবত সংশোধন) করার ক্ষমতা দেয় এবং প্রয়োজনে একটি কাস্টম ত্রুটি বার্তা উত্থাপন করে।
রাজ আরও

10
"ক্যাপচার এবং ফিক্স" এর চেয়ে আরও ঘন ঘন "ক্যাপচার এবং লগ করুন", আমি ভাবি।
কুইলব্রেকার

24
RAISERROR এর বাক্য গঠনটি কমপক্ষে এসকিউএল সার্ভার 2008R2 এবং তার পরেও ভুল। সঠিক সিনট্যাক্সের জন্য দেখুন msdn.microsoft.com/en-us/library/ms178592.aspx
এরিক জে

2
@ বার্নটোকোড লেনদেনের উপস্থিতি নিশ্চিত করার জন্য .. বলুন যে আপনি প্রদত্ত শর্তে (এর মধ্যে try) আপনার লেনদেনটি ফিরিয়ে দিয়েছেন , তবে কোডটি ব্যর্থ হয়। আর কোনও লেনদেন নেই, তবে আপনি এখনও এর মধ্যে চলে যাচ্ছেন catch
গ্যাব্রিয়েল জিএম

42

এমএসএসকিউএল সার্ভার 2016 এর সাথে কাজ করে ত্রুটি বার্তা পাওয়ার কোড এখানে:

BEGIN TRY
    BEGIN TRANSACTION 
        -- Do your stuff that might fail here
    COMMIT
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRAN

        DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE()
        DECLARE @ErrorSeverity INT = ERROR_SEVERITY()
        DECLARE @ErrorState INT = ERROR_STATE()

    -- Use RAISERROR inside the CATCH block to return error  
    -- information about the original error that caused  
    -- execution to jump to the CATCH block.  
    RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH

1
DECLARE @Var TYPE; SET @Var = ERROR;২০০ s সালে এসকিএল সার্ভারে ত্রুটি বাড়াতে আমাকে ব্যবহার করতে হয়েছিল Otherwise অন্যথায় ত্রুটি উত্থাপনের জন্য উপরের কোডটি পুরানো ডিবির ক্ষেত্রেও কাজ করে। একটি স্থানীয় ভেরিয়েবলের জন্য একটি ডিফল্ট মান নির্ধারণের চেষ্টা করা হ'ল সমস্যাটি কী ঘটেছে।
jtlindsey

আপনি একটি সহজ থ্রো ব্যবহার করতে পারেন; RAISERROR এবং ERROR_ * ঘোষণার পরিবর্তে।
রডজমকিই

21

এমডিএসএন নিবন্ধ থেকে, লেনদেন নিয়ন্ত্রণ (ডাটাবেস ইঞ্জিন)

যদি কোনও রান-টাইম স্টেটমেন্ট ত্রুটি (যেমন সীমাবদ্ধতা লঙ্ঘন) কোনও ব্যাচে ঘটে থাকে তবে ডেটাবেস ইঞ্জিনের ডিফল্ট আচরণটি কেবল ত্রুটিটি উত্পন্ন করার বিবৃতিতে ফিরে আসে। আপনি SET XACT_ABORT বিবৃতি ব্যবহার করে এই আচরণটি পরিবর্তন করতে পারেন। SET XACT_ABORT চালু হওয়ার পরে, কোনও রান-টাইম স্টেটমেন্ট ত্রুটি বর্তমান লেনদেনের একটি স্বয়ংক্রিয় রোলব্যাকের কারণ করে। সংকলন ত্রুটিগুলির মতো সংকলন ত্রুটিগুলি SET XACT_ABORT দ্বারা প্রভাবিত হয় না। আরও তথ্যের জন্য, SET XACT_ABORT (লেনদেন-এসকিউএল) দেখুন।

আপনার ক্ষেত্রে কোনও সন্নিবেশ ব্যর্থ হলে এটি সম্পূর্ণ লেনদেনের রোলব্যাক করবে।


3
সিনট্যাক্স ত্রুটিগুলি পরিচালনা করার জন্য আমাদের কী দরকার? বা ত্রুটি সংকলন? তাদের মধ্যে যদি কেউ ঘটে তবে পুরো লেনদেনটি আবার ফিরিয়ে নেওয়া উচিত
MonsterMMORPG

স্কেচিং সংকলন / সিনট্যাক্স ত্রুটিগুলি এসএসডিটি প্রকল্পগুলির জন্য। :-)
জো দ্য কোডার

10

যদি সন্নিবেশগুলির মধ্যে একটি ব্যর্থ হয়, বা কমান্ডের কোনও অংশ ব্যর্থ হয়, তবে এসকিউএল সার্ভার লেনদেনকে পিছনে ফেলবে?

না, তা হয় না।

যদি এটি রোলব্যাক না করে, তবে কি এটি আবার রোল করার জন্য আমাকে একটি দ্বিতীয় কমান্ড প্রেরণ করতে হবে?

অবশ্যই, আপনি ROLLBACKপরিবর্তে ইস্যু করা উচিতCOMMIT

আপনি যদি লেনদেন প্রতিশ্রুতিবদ্ধ বা রোলব্যাক করবেন কিনা তা সিদ্ধান্ত নিতে চান, আপনার COMMITবক্তব্যটির বাইরে থাকা বাক্যটি সরিয়ে ফেলা উচিত , সন্নিবেশকারীর ফলাফলগুলি পরীক্ষা করা উচিত এবং তারপরে COMMITবা ROLLBACKচেকের ফলাফলের উপর নির্ভর করে ইস্যু করা উচিত ।


সুতরাং যদি আমি একটি ত্রুটি পাই তবে "প্রাথমিক কী সংঘাত" বলুন আমাকে রোলব্যাকে দ্বিতীয় কল পাঠাতে হবে? আমি বুঝতে পারি যে এটি উপলব্ধি করে। কোনও নেটওয়ার্ক-সম্পর্কিত ত্রুটি যেমন খুব দীর্ঘ চলমান এসকিউএল স্টেটমেন্ট চলাকালীন সংযোগটি বিচ্ছিন্ন হয়ে যায় তবে কি হবে?
জোনাথন্পিপারস

2
কোনও সংযোগ শেষ হয়ে গেলে, অন্তর্নিহিত নেটওয়ার্ক প্রোটোকল (যেমন Named Pipesবা TCP) সংযোগটি ভেঙে দেয়। কোনও সংযোগ নষ্ট হয়ে গেলে, SQL Serverবর্তমানে চলমান সমস্ত কমান্ড বন্ধ করে এবং লেনদেনটি রোলব্যাক করে।
কাসনসুই

1
তাই ডাইংক্যাকটাসের সমাধান দেখে মনে হচ্ছে এটি আমার সমস্যাটিকে ঠিক করে দিয়েছে, সহায়তার জন্য ধন্যবাদ।
জোনাথনপ্পিয়ার্স

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