প্রথমত , আপনার সর্বদা আপনার সমস্ত পদ্ধতিতে যথাযথ লেনদেন হ্যান্ডলিং করা উচিত যাতে এগুলিকে অ্যাপ কোড দ্বারা, অন্য কোনও পদ্ধতি দ্বারা, পৃথকভাবে কোনও এস -কিউএল এজেন্ট কাজ দ্বারা, বা অন্য কোনও উপায়ে অ্যাড-হক জিজ্ঞাসায় ডেকে আনে কিনা তা বিবেচ্য নয় does । তবে একক ডিএমএল বিবৃতি, বা কোড যা কোনও পরিবর্তন করে না, তাদের সুস্পষ্ট লেনদেনের প্রয়োজন হয় না । সুতরাং, আমি যা প্রস্তাব দিচ্ছি তা হ'ল:
- সর্বদা TRY / CATCH কাঠামো রাখুন যাতে ত্রুটিগুলি সঠিকভাবে বুদ্বুদ হতে পারে
- আপনার একাধিক ডিএমএল স্টেটমেন্ট থাকলে (একক বিবৃতি নিজেই একটি লেনদেন হওয়ায়) নীচের কোডটিতে 3 টি লেনদেনের হ্যান্ডলিং টুকরো বিকল্পভাবে অন্তর্ভুক্ত করুন। যাইহোক, কিছু অতিরিক্ত কোড যুক্ত করার বাইরে যেখানে এটি নির্দিষ্টভাবে প্রয়োজন হয় না, যদি কারও একটি ধারাবাহিক টেম্পলেট পছন্দ হয়, তবে 3 লেনদেন-সম্পর্কিত আইএফ ব্লকগুলিতে রাখলে ক্ষতি হয় না। তবে সেক্ষেত্রে আমি এখনও কেবলমাত্র কেবলমাত্র নির্বাচন (কেবল পঠনযোগ্য) প্রক্সের জন্য 3 লেনদেন-সম্পর্কিত আইএফ ব্লক না রাখার পরামর্শ দেব।
যখন 2 বা তার বেশি DML বিবৃতি করছেন, আপনি প্রয়োজন নিম্নলিখিত লাইনের (এটিও একক DML অপারেশনের জন্য কাজ করা যেতে পারে যদি এক সামঞ্জস্যপূর্ণ হতে পছন্দ করে) বরাবর কিছু ব্যবহার করার জন্য:
CREATE PROCEDURE [SchemaName].[ProcedureName]
(
@Param DataType
...
)
AS
SET NOCOUNT ON;
DECLARE @InNestedTransaction BIT;
BEGIN TRY
IF (@@TRANCOUNT = 0)
BEGIN
SET @InNestedTransaction = 0;
BEGIN TRAN; -- only start a transaction if not already in one
END;
ELSE
BEGIN
SET @InNestedTransaction = 1;
END;
-- { 2 or more DML statements (i.e. INSERT / UPDATE / DELETE) }
IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0)
BEGIN
COMMIT;
END;
END TRY
BEGIN CATCH
IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0)
BEGIN
ROLLBACK;
END;
DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE(),
@ErrorState INT = ERROR_STATE(),
@ErrorSeverity INT = ERROR_SEVERITY();
-- optionally concatenate ERROR_NUMBER() and/or ERROR_LINE() into @ErrorMessage
RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
RETURN;
END CATCH;
মাত্র 1 ডিএমএল বিবৃতি বা কেবল একটি নির্বাচন করার সময়, আপনি কেবল নিম্নলিখিতটি দিয়ে পালাতে পারেন:
CREATE PROCEDURE [SchemaName].[ProcedureName]
(
@Param DataType
...
)
AS
SET NOCOUNT ON;
BEGIN TRY
-- { 0 or 1 DML statements (i.e. INSERT / UPDATE / DELETE) }
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE(),
@ErrorState INT = ERROR_STATE(),
@ErrorSeverity INT = ERROR_SEVERITY();
-- optionally concatenate ERROR_NUMBER() and/or ERROR_LINE() into @ErrorMessage
RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
RETURN;
END CATCH;
দ্বিতীয়ত আপনি অ্যাপ্লিকেশানটি স্তর এ লেনদেন হ্যান্ডেল করা হয় শুধুমাত্র যদি আপনি চেয়ে বেশি 1 ক্যোয়ারী / সঞ্চিত পদ্ধতি চালানো প্রয়োজন এবং তারা সব প্রয়োজন একটি পারমাণবিক অপারেশন গোষ্ঠীতে বিভক্ত করা হবে। একক করার জন্য SqlCommand.Execute___
কেবল চেষ্টা / ধরা থাকা দরকার তবে কোনও লেনদেনে নয়।
কিন্তু, কেবলমাত্র একক কল করার সময় অ্যাপ স্তরে কোনও লেনদেন করা ব্যথা করে? যদি এটির এমএসডিটিসি (মাইক্রোসফ্ট ডিস্ট্রিবিউটড ট্রানজেকশন কো-অর্ডিনেটর) প্রয়োজন হয় তবে স্পষ্টভাবে প্রয়োজন না হলে অ্যাপ্লিকেশন স্তরে এটি করা সিস্টেমে আরও ভারী। ব্যক্তিগতভাবে, আমি অনাথ লেনদেনের সম্ভাব্যতাগুলি হ্রাস না করে (যদি কমিট বা রোলব্যাক করার আগে অ্যাপ্লিকেশন কোডটিতে কোনও ভুল হয়ে থাকে) তবে অ্যাপ লেয়ার-ভিত্তিক লেনদেন এড়াতে পছন্দ করি। আমি এটিও পেয়েছি যে এটি কখনও কখনও নির্দিষ্ট পরিস্থিতিগুলি ডিবাগিংকে আরও কিছুটা কঠিন করে তোলে। কিন্তু যে হচ্ছে বলেন, আমি কিছুই দেখছি না টেকনিক্যালি ভুল এছাড়াও যখন একটি একক উপার্জন অ্যাপ্লিকেশন স্তর এ লেনদেন পরিচালনার procজন্ম দেয়; আবার কোনও একক ডিএমএল স্টেটমেন্টটি তার নিজস্ব লেনদেন এবং উভয় স্তরে সুস্পষ্ট লেনদেনের প্রয়োজন হয় না ।