টিএল; ডিআর / এক্সিকিউটিভ সংক্ষিপ্তসার: প্রশ্নের এই অংশ সম্পর্কিত:
আমি কি মামলা নিয়ন্ত্রণ ভিতরে পাশ করা যাবে না দেখতে পান CATCH
একটি লেনদেন যে প্রতিশ্রুতিবদ্ধ হতে পারে যখন XACT_ABORT
সেট করা হয়ON
।
আমি বেশ এখন এই পরীক্ষা একটি বিট কাজ করেছেন এবং আমি কোন ক্ষেত্রে যেখানে খুঁজে পাচ্ছি না XACT_STATE()
আয় 1
একটি ভেতরে CATCH
ব্লক যখন @@TRANCOUNT > 0
এবং এর অধিবেশন সম্পত্তি XACT_ABORT
হল ON
। এবং প্রকৃতপক্ষে, SET XACT_ABORT এর জন্য বর্তমান এমএসডিএন পৃষ্ঠা অনুসারে :
যখন SET XACT_ABORT চালু থাকে, কোনও লেনদেন-এসকিউএল বিবৃতি যদি রান-টাইম ত্রুটি উত্থাপন করে তবে পুরো লেনদেনটি বন্ধ হয়ে যায় এবং ফিরে আসে।
এই বিবৃতিটি আপনার জল্পনা এবং আমার অনুসন্ধানগুলির সাথে একমত বলে মনে হচ্ছে।
এমএসডিএন নিবন্ধটির SET XACT_ABORT
একটি উদাহরণ রয়েছে যখন কোনও লেনদেনের ভিতরে কিছু বিবৃতি সফলভাবে কার্যকর হয় এবং কিছু XACT_ABORT
সেট হয়ে থাকে যখন সেট থাকে isOFF
এটা ঠিক যে, কিন্তু যে উদাহরণে বিবৃতি না একটি মধ্যে TRY
ব্লক। কোনও TRY
ব্লকের মধ্যে একই বিবৃতিগুলি ত্রুটির কারণ হয়ে যাওয়ার পরে কোনও বিবৃতি কার্যকর করার পরে আটকাতে পারে, তবে ধরে নেওয়া XACT_ABORT
হয় OFF
, যখন নিয়ন্ত্রণটি CATCH
ব্লকের কাছে পৌঁছে যায় তখন ট্রানজেকশনটি শারীরিকভাবে বৈধ যে পূর্ববর্তী সমস্ত পরিবর্তন ত্রুটি ছাড়াই ঘটেছিল did এবং প্রতিশ্রুতিবদ্ধ হতে পারে, যদি এটি ইচ্ছা হয়, বা সেগুলি ঘূর্ণিত হতে পারে। অন্যদিকে, যদি XACT_ABORT
হয় ON
তবে পূর্বের যে কোনও পরিবর্তনগুলি স্বয়ংক্রিয়ভাবে ঘূর্ণিত হয় - এবং তারপরে আপনার পছন্দ হয়: ক) একটি জারি করুনROLLBACK
লেনদেন ইতিমধ্যে বিয়োগ পুনরায় সেট @@TRANCOUNT
করতে ব্যর্থ হয়েছে 0
, বা খ) একটি ত্রুটি পেয়ে যা বেশিরভাগই পরিস্থিতির একটি গ্রহণযোগ্যতা । পছন্দ খুব একটা না, তাই না?
এই ধাঁধাটির একটি সম্ভবত গুরুত্বপূর্ণ বিশদ যা এই ডকুমেন্টেশনের ক্ষেত্রে আপাত নয়, তা SET XACT_ABORT
হ'ল এই সেশন সম্পত্তি, এবং সেই উদাহরণ কোডটিও এসকিউএল সার্ভার 2000 (ডকুমেন্টেশনগুলি সংস্করণগুলির মধ্যে প্রায় অভিন্ন) রয়েছে TRY...CATCH
যা নির্মাণের পূর্বাভাস দিয়েছিল SQL সার্ভার 2005 সালে চালু করে ডকুমেন্টেশন এ খুঁজছি আবার এবং (উদাহরণস্বরূপ দিকে তাকিয়ে ছাড়াTRY...CATCH
), ব্যবহার XACT_ABORT ON
কারণ একটি তাৎক্ষণিক লেনদেনের রোল-ব্যাক: সেখানে "uncommittable" (দয়া করে মনে রাখবেন কোন লেনদেন রাষ্ট্র এ কোনো উল্লেখ আছে যে সমস্ত " SET XACT_ABORT
ডকুমেন্টেশনে " আপত্তিজনক "লেনদেনের রাজ্য )।
আমি মনে করি যে এটি যুক্তিযুক্ত হওয়া যুক্তিযুক্ত:
TRY...CATCH
এসকিউএল সার্ভার ২০০ the- এ কনস্ট্রাক্টের প্রবর্তন একটি নতুন ট্রানজেকশন স্টেটের (যেমন "আপত্তিহীন") এবং XACT_STATE()
তথ্যটি পেতে ফাংশনের প্রয়োজনীয়তা তৈরি করেছিল।
- নিম্নলিখিত কোনও দুটি সত্য হলে
XACT_STATE()
একটি CATCH
ব্লকে চেক করা সত্যই তা উপলব্ধি করতে পারে:
XACT_ABORT
হয় OFF
(অন্যথায় XACT_STATE()
সর্বদা ফিরে আসা উচিত -1
এবং @@TRANCOUNT
আপনার যা প্রয়োজন তা হ'ল )
- আপনি যুক্তি আছে
CATCH
শৃঙ্খল যদি কল নেস্টেড হয়, পরিবর্তন (ক তোলে আপ ব্লক, অথবা কোথাও COMMIT
বা এমনকি কোনো DML, DDL, ইত্যাদি বিবৃতি) পরিবর্তে একটি করছেন ROLLBACK
। (এটি একটি অতি সাধারণ ব্যবহারের ক্ষেত্রে) ** দয়া করে সর্বদা XACT_STATE()
পরিবর্তে মাইক্রোসফ্ট দ্বারা পরীক্ষা করার জন্য মাইক্রোসফ্ট কর্তৃক একটি অনানুষ্ঠানিক সুপারিশ সম্পর্কিত, আপডেট 3 বিভাগে নীচের অংশে নোটটি দেখুন @@TRANCOUNT
এবং কেন পরীক্ষাগুলি দেখায় যে তাদের যুক্তিটি বেরিয়ে আসে না।
TRY...CATCH
এসকিউএল সার্ভার ২০০ the- এ কনস্ট্রাক্টের প্রবর্তনটি বেশিরভাগ অংশে XACT_ABORT ON
সেশন সম্পত্তিটি অচল করে দেয় কারণ এটি লেনদেনের উপর একটি বৃহত্তর ডিগ্রি নিয়ন্ত্রণের ব্যবস্থা করে (আপনার কাছে অন্তত বিকল্প রয়েছে COMMIT
, যদি XACT_STATE()
ফিরে না আসে তবে -1
)।
এই তাকান আরেকটি উপায় হল, পূর্বে SQL সার্ভার 2005 সালের , XACT_ABORT ON
যখন একটি ত্রুটি ঘটেছে স্টপ প্রক্রিয়াকরণ একটি সহজ এবং নির্ভরযোগ্য উপায় প্রদান পরীক্ষণ তুলনায় @@ERROR
প্রতিটি বিবৃতি পরে।
- এর জন্য ডকুমেন্টেশনের উদাহরণ কোডটি
XACT_STATE()
ভুল, বা সর্বোত্তম বিভ্রান্তিকর, এতে এটি XACT_STATE() = 1
কখন রয়েছে XACT_ABORT
তা পরীক্ষা করা দেখায় ON
।
দীর্ঘ অংশ ;-)
হ্যাঁ, এমএসডিএন-তে সেই উদাহরণ কোডটি কিছুটা বিভ্রান্তিকর (এটিও দেখুন: @@ ট্রানট্যাক্ট (রোলব্যাক) বনাম XACT_STATE ) ;-)। আর, আমি এটা কারণ এটা হয় শো এমন কিছু বিষয় যা কোন অর্থে (কারণ আপনি জিজ্ঞাসা করা হয় প্রায়: আপনি এমনকি একটি "committable" লেনদেনের থাকতে পারে তোলে বিভ্রান্তিকর হয় মনে CATCH
ব্লক যখন XACT_ABORT
হয় ON
), অথবা এমনকি এটি সম্ভব, এটা এখনও একটি প্রযুক্তিগত সম্ভাবনার দিকে মনোনিবেশ করে যা খুব কম লোকই চাইবে বা প্রয়োজন হবে এবং যে কারণে এটির বেশি সম্ভাবনা রয়েছে তার কারণটি উপেক্ষা করে।
TRY ব্লকের ভিতরে যদি তীব্র পর্যাপ্ত ত্রুটি থাকে তবে নিয়ন্ত্রণটি ক্যাচটিতে চলে যাবে। সুতরাং, আমি যদি ক্যাচের অভ্যন্তরে থাকি তবে আমি জানি যে লেনদেনের কোনও সমস্যা হয়েছে এবং সত্যই একমাত্র বুদ্ধিমানের কাজটি করার ক্ষেত্রে এটি আবার ঘুরিয়ে দেওয়া, তাই না?
আমি মনে করি যদি আমরা কিছু নির্দিষ্ট শব্দ এবং ধারণা দ্বারা বোঝানো হয় সে বিষয়ে আমরা একই পৃষ্ঠায় রয়েছি কিনা তা নিশ্চিত করে নিলে এটি সহায়তা করবে:
"গুরুতর পর্যাপ্ত ত্রুটি": কেবল পরিষ্কার করার জন্য, ট্রাই ... ক্যাচ বেশিরভাগ ত্রুটি জাল করবে। যা ধরা পড়বে না তার তালিকা সেই লিঙ্কযুক্ত এমএসডিএন পৃষ্ঠায় "একটি ট্রাই দ্বারা আটকানো ত্রুটি… ক্যাচ কনস্ট্রাক্ট" বিভাগের অধীনে তালিকাভুক্ত করা হয়েছে।
"আমি যদি ক্যাচের অভ্যন্তরে থাকি তবে আমি জানি যে লেনদেনের কোনও সমস্যা হয়েছে" (এম ফ্যাস যোগ করা হয়েছে): যদি "লেনদেন" বলতে আপনার অর্থ লজিক্যাল ইউনিটকে আপনার দ্বারা সুস্পষ্ট লেনদেনে বিভাজনকে দলবদ্ধ করে নির্ধারিত করে থাকে, তবে সম্ভবত হ্যাঁ আমি মনে করি আমাদের বেশিরভাগ ডিবি লোকেরা সম্মত হবেন যে রোলিং ব্যাক হ'ল "একমাত্র বুদ্ধিমান কাজ" যেহেতু আমরা কীভাবে এবং কেন স্পষ্ট লেনদেন ব্যবহার করি এবং কী কী পদক্ষেপগুলি পরমাণু ইউনিট গঠন করা উচিত তা সম্পর্কে আমাদের একই মতামত থাকতে পারে কাজ এর.
তবে, যদি আপনি বোঝাতে চান কাজের প্রকৃত ইউনিটগুলি যা সুস্পষ্ট লেনদেনের জন্য দলবদ্ধ করা হচ্ছে, তবে না, আপনি জানেন না যে লেনদেনে নিজেই কোনও সমস্যা হয়েছে। আপনি কেবল জানেন যে সুস্পষ্টভাবে সংজ্ঞায়িত লেনদেনের মধ্যে সম্পাদিত একটি বিবৃতি একটি ত্রুটি বাড়িয়েছে। তবে এটি কোনও ডিএমএল বা ডিডিএল বিবৃতি নাও হতে পারে। এমনকি এটি ডিএমএল বিবৃতি হলেও, লেনদেনটি নিজেই দায়বদ্ধ হতে পারে।
উপরোক্ত দুটি পয়েন্ট দেওয়া, আমাদের সম্ভবত "যে" প্রতিশ্রুতিবদ্ধ "করতে পারে না এবং যেটি আপনি করতে চান না" এর মধ্যে "লেনদেনের মধ্যে একটি পার্থক্য আঁকতে হবে।
যখন XACT_STATE()
আয় একটি 1
, তার মানে তাদের লেনদেন "committable" হয়, তাহলে আপনি মধ্যে একটা চয়েস আছে COMMIT
বা ROLLBACK
। আপনি এটি প্রতিশ্রুতিবদ্ধ হতে নাও চান , তবে যদি কোনও কারণে-যেমন-উদাহরণ-সহকারে কঠোর-এমনকি-সমালোচনার জন্য-আসতে থাকে তবে কমপক্ষে আপনি করতে পারেন কারণ লেনদেনের কিছু অংশ সফলতার সাথে সম্পন্ন হয়েছিল।
তবে যখন XACT_STATE()
কোনও ফেরত দেয় -1
, তখন আপনার সত্যিকারের প্রয়োজন ROLLBACK
কারণ লেনদেনের কিছু অংশ খারাপ অবস্থায় চলে যায়। এখন, আমি একমত যে যদি নিয়ন্ত্রণটি ক্যাচ ব্লকে পৌঁছে দেওয়া হয়, তবে এটি কেবলমাত্র পরীক্ষা করা যথেষ্ট পরিমাণে বোঝা যায় @@TRANCOUNT
, কারণ আপনি যদি লেনদেন করতে পারেন, কেন আপনি চান?
আপনি যদি উদাহরণের শীর্ষে লক্ষ্য করেন তবে XACT_ABORT ON
কিছু কিছু পরিবর্তন করে। আপনি একটি নিয়মিত ত্রুটি থাকতে পারে, করছেন পরে BEGIN TRAN
বুঝতে পারা ব্লক নিয়ন্ত্রণ পাস হবে যখন XACT_ABORT
হয় OFF
এবং XACT_STATE () ফিরে আসবে 1
। তবে, যদি XACT_ABORT হয় ON
তবে কোনও 'ত্রুটি ত্রুটির জন্য লেনদেন "বাতিল" (অর্থাত অবৈধ) হয় এবং তারপরে XACT_STATE()
ফিরে আসবে -1
। এই ক্ষেত্রে, এটা চেক করতে বেহুদা মনে হয় XACT_STATE()
মধ্যে CATCH
ব্লক হিসাবে এটা সবসময় একটি আসতে বলে মনে হয় -1
যখন XACT_ABORT
হয় ON
।
তাহলে কি XACT_STATE()
জন্য? কিছু ক্লু হ'ল:
TRY...CATCH
"আপত্তিজনক লেনদেন এবং XACT_STATE" বিভাগের অধীনে এমএসডিএন পৃষ্ঠাটি বলে:
সাধারণত একটি ট্রিওয়াই ব্লকের বাইরে লেনদেন শেষ করে এমন একটি ত্রুটি যখন একটি ট্রাই ব্লকের ভিতরে ত্রুটি ঘটে তখন একটি লেনদেনটিকে একটি দ্বিধাবিহীন অবস্থায় প্রবেশ করে।
"মন্তব্যগুলি" বিভাগের অধীনে SET XACT_ABORT এর জন্য এমএসডিএন পৃষ্ঠাটি বলেছেন:
যখন এসইটি XACT_ABORT বন্ধ থাকে, কিছু ক্ষেত্রে কেবল ত্রুটি উত্থাপিত ট্রান্সঅ্যাক্ট-এসকিউএল বিবৃতি আবার ঘুরিয়ে দেওয়া হয় এবং লেনদেন প্রক্রিয়াজাতকরণ অব্যাহত থাকে।
এবং:
এসএকিউএল সার্ভার সহ বেশিরভাগ ওএলডি ডিবি সরবরাহকারীদের বিরুদ্ধে একটি স্পষ্ট বা স্পষ্ট লেনদেনের ক্ষেত্রে ডেটা সংশোধন বিবরণের জন্য XACT_ABORT টি চালু থাকতে হবে।
"মন্তব্যগুলি" বিভাগের অধীনে শুরু হওয়া বিগইন ট্রান্সএকশনের জন্য এমএসডিএন পৃষ্ঠাটি বলেছেন:
বিগইন ট্রান্সএকশন বিবৃতি দিয়ে শুরু হওয়া স্থানীয় লেনদেন বিতরণ লেনদেনে বাড়ানো হয় যদি বিবৃতিটি প্রতিশ্রুতিবদ্ধ বা ফিরে ঘোরানোর আগে নিম্নলিখিত ক্রিয়া সম্পাদিত হয়:
- সংযুক্ত সার্ভারে একটি দূরবর্তী টেবিলের উল্লেখ করে একটি INSERT, মোছা বা আপডেটের বিবৃতি কার্যকর করা হয়। সংযুক্ত সার্ভারটি অ্যাক্সেস করতে ব্যবহৃত OLE DB সরবরাহকারী ITransactionJoin ইন্টারফেস সমর্থন না করে যদি INSERT, আপডেট, বা মোছার বিবৃতি ব্যর্থ হয়।
সর্বাধিক প্রযোজ্য ব্যবহারটি লিঙ্কযুক্ত সার্ভারের ডিএমএল স্টেটমেন্টের প্রসঙ্গে রয়েছে বলে মনে হয়। এবং আমি বিশ্বাস করি যে আমি নিজেই এটির মধ্যে বেশ কয়েক বছর আগে চলে এসেছি। আমি সমস্ত বিবরণ মনে রাখিনা, তবে এটি রিমোট সার্ভারটি উপলব্ধ না হওয়ার সাথে কিছু করার ছিল এবং কোনও কারণে, ত্রুটিটি ট্রাই ব্লকের মধ্যে ধরা পড়েনি এবং কখনও ক্যাশে পাঠানো হয়নি এবং তাই এটি হয়েছিল did একটি কমিটি যখন এটি না করা উচিত। অবশ্যই, যে পারে না বলে একটা ব্যাপার আছে হয়েছে XACT_ABORT
সেট ON
বদলে চেক করতে ব্যর্থ XACT_STATE()
, অথবা সম্ভবত উভয়। এবং আমি এমন কিছু পড়ার কথা মনে করি যা বলেছিল যে আপনি যদি লিঙ্কযুক্ত সার্ভার এবং / অথবা বিতরণ লেনদেন ব্যবহার করেন তবে আপনাকে ব্যবহার করার প্রয়োজন ছিল XACT_ABORT ON
এবং / অথবা XACT_STATE()
, তবে আমি এখন এই নথিটি খুঁজে পাচ্ছি না। যদি আমি এটি খুঁজে পাই তবে আমি লিঙ্কটি সহ এটি আপডেট করব।
তবুও, আমি বেশ কয়েকটি জিনিস চেষ্টা করে দেখেছি এবং প্রতিবেদন করার সাথে সাথে ব্লকের XACT_ABORT ON
নিয়ন্ত্রণ ও এমন দৃশ্যের সন্ধান করতে অক্ষম ।CATCH
XACT_STATE()
1
XACT_ABORT
এর মানটির প্রভাব দেখতে এই উদাহরণগুলি ব্যবহার করে দেখুন XACT_STATE()
:
SET XACT_ABORT OFF;
BEGIN TRY
BEGIN TRAN;
SELECT 1/0 AS [DivideByZero]; -- error, yo!
COMMIT TRAN;
END TRY
BEGIN CATCH
SELECT @@TRANCOUNT AS [@@TRANCOUNT],
XACT_STATE() AS [XactState],
ERROR_MESSAGE() AS [ErrorMessage]
IF (@@TRANCOUNT > 0)
BEGIN
ROLLBACK;
END;
END CATCH;
GO ------------------------------------------------
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRAN;
SELECT 1/0 AS [DivideByZero]; -- error, yo!
COMMIT TRAN;
END TRY
BEGIN CATCH
SELECT @@TRANCOUNT AS [@@TRANCOUNT],
XACT_STATE() AS [XactState],
ERROR_MESSAGE() AS [ErrorMessage]
IF (@@TRANCOUNT > 0)
BEGIN
ROLLBACK;
END;
END CATCH;
GO ------------------------------------------------
SET XACT_ABORT ON;
BEGIN TRY
SELECT 1/0 AS [DivideByZero]; -- error, yo!
END TRY
BEGIN CATCH
SELECT @@TRANCOUNT AS [@@TRANCOUNT],
XACT_STATE() AS [XactState],
ERROR_MESSAGE() AS [ErrorMessage]
END CATCH;
হালনাগাদ
মূল প্রশ্নের অংশ না হলেও, এই উত্তরের এই মন্তব্যের ভিত্তিতে:
আমি ত্রুটি ও লেনদেন পরিচালনার বিষয়ে এরল্যান্ডের নিবন্ধগুলি পড়ছি যেখানে তিনি বলেছেন যে উত্তরাধিকারগত কারণে XACT_ABORT
মূলত এটি হয় OFF
এবং সাধারণত আমাদের এটি সেট করা উচিত ON
।
...
"... আপনি যদি প্রস্তাবটি অনুসরণ করেন এবং SET XACT_ABORT চালু রেখে যান তবে লেনদেন সর্বদা সর্বনাশ হয়ে যায়।"
XACT_ABORT ON
সর্বত্র ব্যবহার করার আগে , আমি প্রশ্ন করব: এখানে ঠিক কী অর্জন করা হচ্ছে? আমি এটি করা প্রয়োজন বলে মনে করি না এবং সাধারণত প্রয়োজন হয় তবে আপনার এটি ব্যবহার করা উচিত এমন পরামর্শও দিয়েছেন। ROLLBACK
আপনি @ রিমাসের উত্তরে দেখানো টেম্পলেট ব্যবহার করে আপনি সহজেই হ্যান্ডেল করতে চান বা না চান , বা যেটি আমি বছরের পর বছর ধরে ব্যবহার করছি যা মূলত একই জিনিস তবে সেভ পয়েন্ট ছাড়াই, এই উত্তরে দেখানো হয়েছে (যা কোনটি নেস্টেড কলগুলি পরিচালনা করে):
আমাদের কি সি # কোড এবং সেই সাথে সঞ্চিত পদ্ধতিতে লেনদেন পরিচালনা করতে হবে?
আপডেট 2
আমি এই মুহূর্তে একটি ছোট্ট নেট নেট কনসোল অ্যাপ তৈরি করে, কোনও অ্যাপ্লিকেশন কার্যকর করার আগে অ্যাপ্লিকেশন স্তরে একটি লেনদেন তৈরি SqlCommand
করে (যেমন মাধ্যমে using (SqlTransaction _Tran = _Connection.BeginTransaction()) { ...
), পাশাপাশি কেবল বিবৃতি না দিয়ে ব্যাচ-অ্যাওর্টিং ত্রুটি ব্যবহার করে আমি আরও কিছু পরীক্ষা করেছি I -বোর্টিং ত্রুটি, এবং এটি খুঁজে পেয়েছে:
- একটি "আপত্তিজনক" লেনদেন হ'ল এটি বেশিরভাগ অংশে ইতিমধ্যে ঘুরে ফিরে গেছে (পরিবর্তনগুলি পূর্বাবস্থায় ফিরে এসেছে) তবে
@@TRANCOUNT
এখনও 0% is
- যখন আপনার একটি "আপত্তিজনক" লেনদেন হয় আপনি লেনদেনটি "আপত্তিজনক"
COMMIT
বলে ত্রুটি করে এমনটি উত্পন্ন করতে পারবেন না । আপনি এটিকে উপেক্ষাও করতে পারবেন না বা কিছুই করবেন না কারণ ত্রুটি উত্পন্ন হবে যখন ব্যাচ শেষ করে বলেছিল যে ব্যাচটি দীর্ঘকালীন, আপত্তিজনক লেনদেনের মাধ্যমে সম্পন্ন হয়েছে এবং এটি আবার ঘুরিয়ে দেওয়া হবে (সুতরাং, যদি এটি যাইহোক অটো-রোল-ব্যাক হবে, ত্রুটি ছুড়ে কেন বিরক্ত করবেন?)। সুতরাং আপনাকে অবশ্যই একটি স্পষ্ট ইস্যু করতে হবেROLLBACK
, সম্ভবত তাড়াতাড়ি CATCH
ব্লকে নয়, তবে ব্যাচটি শেষ হওয়ার আগেই।
- কোন
TRY...CATCH
কনস্ট্রাক্টে, কখন XACT_ABORT
হয় OFF
, ত্রুটিগুলি যা লেনদেনের স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায় যদি সেগুলি কোনও TRY
ব্লকের বাইরে ঘটে থাকে যেমন ব্যাচ-গর্ভপাত ত্রুটিগুলি, কাজটিকে পূর্বাবস্থায় ফিরিয়ে দেবে তবে ট্রানসেকশনটি সমাপ্ত করবে না, এটিকে "আপত্তিজনক" হিসাবে রেখে যাবে। ROLLBACK
লেনদেন বন্ধ করার জন্য একটি ইস্যু করা আরও আনুষ্ঠানিকতার প্রয়োজন, তবে ইতিমধ্যে কাজটি রোলড-ব্যাক হয়েছে।
- কখন
XACT_ABORT
হয় ON
, বেশিরভাগ ত্রুটি ব্যাচ-গর্ভপাত হিসাবে কাজ করে এবং তাই সরাসরি বুলেট পয়েন্টে উপরে বর্ণিত হিসাবে আচরণ করে (# 3)।
XACT_STATE()
, ত্রুটির সময়ে কোনও সক্রিয় লেনদেন থাকলে কমপক্ষে কোনও CATCH
ব্লকে, -1
ব্যাচ-অ্যাওর্টিং ত্রুটির জন্য একটি প্রদর্শন করবে ।
XACT_STATE()
1
কোনও সক্রিয় লেনদেন না থাকলেও কখনও কখনও ফিরে আসে । যদি @@SPID
(অন্যদের মধ্যে) SELECT
তালিকায় থাকে XACT_STATE()
তবে XACT_STATE()
সক্রিয় লেনদেন না থাকলে 1 ফিরে আসবে। এই আচরণটি এসকিউএল সার্ভার ২০১২ সালে শুরু হয়েছিল এবং এটি ২০১৪-তে উপস্থিত রয়েছে, তবে আমি ২০১ on সালে পরীক্ষা করিনি।
উপরের বিষয়গুলি মাথায় রেখে:
- প্রদত্ত পয়েন্ট # 4 এবং # 5, সবচেয়ে (বা সকলের?) যেহেতু ত্রুটি একটি লেনদেন "uncommitable" রেন্ডার হবে, এটি সম্পূর্ণরূপে চেক করতে অর্থহীন বলে মনে হয়
XACT_STATE()
এ CATCH
ব্লক যখন XACT_ABORT
হয় ON
ফিরে সবসময় হতে হবে মান যেহেতু -1
।
- পরীক্ষা করা হচ্ছে
XACT_STATE()
এ CATCH
ব্লক যখন XACT_ABORT
হয় OFF
আরো ইন্দ্রিয় তোলে কারণ ফেরত মান অন্তত কিছু প্রকরণ থাকবে যেহেতু এটি ফিরে আসবে 1
বিবৃতি-গর্ভপাত ত্রুটির জন্য। তবে, আপনি যদি আমাদের বেশিরভাগের মতো কোড করেন তবে এই পার্থক্যটি অর্থহীন, যেহেতু আপনি ROLLBACK
কোনও ত্রুটি ঘটেছে এই কারণে আপনি যেভাবেই কল করবেন ।
- যদি আপনি এমন কোনও পরিস্থিতি খুঁজে
COMMIT
পান যা CATCH
ব্লকটিতে ওয়ারেন্ট জারি করে , তবে এর মানটি পরীক্ষা করে দেখুন XACT_STATE()
এবং নিশ্চিত হন SET XACT_ABORT OFF;
।
XACT_ABORT ON
মনে হচ্ছে TRY...CATCH
নির্মাণের জন্য কোনও লাভ নেই ।
- আমি এমন কোনও দৃশ্য খুঁজে পাই না যেখানে চেকিং
XACT_STATE()
কেবল চেকিংয়ের মাধ্যমে অর্থবহ সুবিধা দেয় @@TRANCOUNT
।
- যখন এমন কোনও ব্লক যখন
XACT_STATE()
ফিরে আসে তখন আমি এমন কোনও দৃশ্যের সন্ধান করতে পারি না । আমি মনে করি এটি একটি ডকুমেন্টেশন ত্রুটি।1
CATCH
XACT_ABORT
ON
- হ্যাঁ, আপনি এমন কোনও লেনদেনের রোল-ব্যাক করতে পারেন যা আপনি স্পষ্টভাবে শুরু করেননি। এবং ব্যবহারের প্রসঙ্গে
XACT_ABORT ON
, এটি একটি মূল বিন্দু যেহেতু একটি TRY
ব্লকে ঘটে যাওয়া ত্রুটিটি স্বয়ংক্রিয়ভাবে পরিবর্তনগুলি রোল-ব্যাক করবে।
- সম্পূর্ণ লেনদেন স্বয়ংক্রিয়ভাবে বাতিল না
TRY...CATCH
করার ফলে এই কনস্ট্রাক্টের সুবিধা রয়েছে XACT_ABORT ON
এবং তাই লেনদেনের (যতক্ষণ না XACT_STATE()
প্রত্যাবর্তনের সময় পর্যন্ত 1
) প্রতিশ্রুতিবদ্ধ হতে দেওয়া হয় (এমনকি এটি প্রান্তের ক্ষেত্রে হলেও)।
উদাহরণ XACT_STATE()
ফিরে -1
যখন XACT_ABORT
হয় OFF
:
SET XACT_ABORT OFF;
BEGIN TRY
BEGIN TRAN;
SELECT CONVERT(INT, 'g') AS [ConversionError];
COMMIT TRAN;
END TRY
BEGIN CATCH
DECLARE @State INT;
SET @State = XACT_STATE();
SELECT @@TRANCOUNT AS [@@TRANCOUNT],
@State AS [XactState],
ERROR_MESSAGE() AS [ErrorMessage];
IF (@@TRANCOUNT > 0)
BEGIN
SELECT 'Rollin back...' AS [Transaction];
ROLLBACK;
END;
END CATCH;
আপডেট 3
আপডেট 2 বিভাগের আইটেম # 6 এর সাথে সম্পর্কিত ( XACT_STATE()
যেমন কোনও সক্রিয় লেনদেন নেই তখন ফিরে আসা সম্ভব ভুল মান ):
- বিজোড় / ভ্রান্ত আচরণটি এসকিউএল সার্ভার ২০১২ সালে শুরু হয়েছিল (এখনও পর্যন্ত ২০১২ এসপি 2 এবং ২০১৪ এসপি 1 এর বিপরীতে পরীক্ষিত)
- এসকিউএল সার্ভার সংস্করণে ২০০ 2008, ২০০৮ এবং ২০০৮ আর ২-
XACT_STATE()
এ ট্রিগার বা INSERT...EXEC
পরিস্থিতি ব্যবহারের সময় প্রত্যাশিত মানগুলির প্রতিবেদন করা হয়নি : লেনদেনটি ডুমড হয়েছে কিনা তা নির্ধারণের জন্য xact_state () নির্ভরযোগ্যভাবে ব্যবহার করা যায় না । যাইহোক, এই 3 সংস্করণে (আমি শুধুমাত্র 2008 R2 হলো উপর পরীক্ষা) এ, XACT_STATE()
নেই না ভুল রিপোর্ট 1
যখন একটি ব্যবহৃত SELECT
সঙ্গে @@SPID
।
এখানে উল্লিখিত আচরণের বিরুদ্ধে একটি কানেক্ট বাগটি দায়ের করা হয়েছে তবে এটি "ডিজাইন দ্বারা" হিসাবে বন্ধ রয়েছে: এক্সএসিএসএসটিএটি () এসকিউএল 2012 এ একটি ভুল লেনদেনের অবস্থা ফিরিয়ে দিতে পারে । তবে, ডিএমভি থেকে বাছাই করার সময় পরীক্ষাটি করা হয়েছিল এবং এটি সিদ্ধান্তে পৌঁছেছিল যে এটি করার ফলে স্বাভাবিকভাবেই একটি সিস্টেম উত্পন্ন লেনদেন হবে, কমপক্ষে কিছু ডিএমভিতে for এমএসের চূড়ান্ত জবাবে এটিও বলা হয়েছিল যে:
মনে রাখবেন যে কোনও আইএফ স্টেটমেন্ট এবং এফআরএম ছাড়াই একটি নির্বাচন করুন, কোনও লেনদেন শুরু করবেন না।
উদাহরণস্বরূপ, আপনার যদি পূর্বের বিদ্যমান লেনদেন না থাকে তবে SELECT XACT_STATE () চালনা করলে 0 ফিরে আসবে।
নিম্নলিখিত বিবৃতি দিয়ে এই বিবৃতিগুলি ভুল:
SELECT @@TRANCOUNT AS [TRANCOUNT], XACT_STATE() AS [XACT_STATE], @@SPID AS [SPID];
GO
DECLARE @SPID INT;
SET @SPID = @@SPID;
SELECT @@TRANCOUNT AS [TRANCOUNT], XACT_STATE() AS [XACT_STATE], @SPID AS [SPID];
GO
অতএব, নতুন সংযুক্ত ত্রুটি:
কিছু সিস্টেম ভেরিয়েবলের সাথে SEF এ ব্যবহৃত হয় তবে FROM ধারা ছাড়াই XACT_STATE () 1 প্রদান করে
অনুগ্রহ করে নোট করুন যে "XACT_STATE () এ এসকিউএল ২০১২-তে একটি ভুল লেনদেনের অবস্থা ফিরিয়ে দিতে পারে" উপরের সাথে সংযুক্ত আইটেমটি সরাসরি সংযুক্ত করুন, মাইক্রোসফ্ট (ভাল, একটি প্রতিনিধি) বলেছেন:
@@ ট্রান্সকাউন্ট বিগিন ট্রান বিবৃতিগুলির সংখ্যা প্রদান করে। এটি সক্রিয় লেনদেন আছে কিনা তা নির্ভরযোগ্য সূচক নয়। সক্রিয় অটোকোমিট লেনদেন থাকলে XACT_STATE () এছাড়াও 1 প্রদান করে এবং এইভাবে সক্রিয় লেনদেন আছে কিনা তা আরও নির্ভরযোগ্য সূচক।
তবে আমি বিশ্বাস না করার কোনও কারণ খুঁজে পাচ্ছি না @@TRANCOUNT
। নিম্নলিখিত পরীক্ষাটি দেখায় যে @@TRANCOUNT
প্রকৃতপক্ষে 1
একটি স্ব-প্রতিশ্রুতিবদ্ধ লেনদেনে ফিরে আসে :
--- begin setup
GO
CREATE PROCEDURE #TransactionInfo AS
SET NOCOUNT ON;
SELECT @@TRANCOUNT AS [TranCount],
XACT_STATE() AS [XactState];
GO
--- end setup
DECLARE @Test TABLE (TranCount INT, XactState INT);
SELECT * FROM @Test; -- no rows
EXEC #TransactionInfo; -- 0 for both fields
INSERT INTO @Test (TranCount, XactState)
EXEC #TransactionInfo;
SELECT * FROM @Test; -- 1 row; 1 for both fields
আমি একটি ট্রিগার দিয়ে একটি বাস্তব টেবিলেও পরীক্ষা করেছিলাম এবং স্পষ্টভাবে কোনও ট্রানজেকশন শুরু না হওয়া সত্ত্বেও @@TRANCOUNT
ট্রিগারটির মধ্যে সঠিকভাবে রিপোর্ট 1
করেছিলাম।
XACT_ABORT
করা উচিতON
বা উচিতOFF
।