c# - TransactionScope vs Transaction في LINQ إلى SQL




linq-to-sql (5)

سوف تستخدم Linq2SQL معاملة ضمنية. إذا تمت جميع تحديثاتك في إرسال واحد ، فقد لا تحتاج إلى التعامل مع المعاملة بنفسك.

من الوثائق (التأكيد على الألغام):

عند استدعاء SubmitChanges ، يتحقق LINQ إلى SQL لمعرفة ما إذا كانت المكالمة في نطاق معاملة أو إذا تم تعيين الخاصية Transaction (IDbTransaction) إلى معاملة محلية المستخدم. إذا لم تعثر على المعاملة ، فسيبدأ LINQ إلى SQL معاملة محلية (IDbTransaction) ويستخدمها لتنفيذ أوامر SQL التي تم إنشاؤها. عند اكتمال كافة أوامر SQL بنجاح ، يقوم LINQ إلى SQL بإجراء المعاملة المحلية والعودة.

ما هي الاختلافات بين نمط المعاملة الكلاسيكية في LINQ إلى SQL مثل:

using(var context = Domain.Instance.GetContext())
{
    try
    {
        context.Connection.Open();
        context.Transaction = context.Connection.BeginTransaction();
        /*code*/
        context.Transaction.Commit();
    }
    catch
    {
        context.Transaction.Rollback();
    }         
}

ضد كائن TransactionScope

using (var context = Domain.Instance.GetContext())
using (var scope = new TransactionScope())
{
    try
    {
        /*code*/
        scope.Complete();
    }
    catch
    {
    }
}

أعتقد أنها بشكل أساسي نفس أن فئة TransactionScope سوف تتفاعل مع اتصال ADO.NET الأساسي لإنشاء إما الالتزام أو التراجع عن المعاملة. أن تم إنشاء فئة TransactionScope للتو لجعل العمل مع نظافة استمرار ADO.NET.

تحرير: توضيح بياني فيما يتعلق بإضافة casperOne هو TransactionScope الذي سيقوم بإنشاء المعاملة وسيشاهد الاتصال ثم المعاملة التي تم إنشاؤها بواسطة TransactionScope واستخدامها حيث أنها متوفرة.


وتجدر الإشارة إلى أنه عند استخدام TransactionScope ليست هناك حاجة لبناء try/catch لديك. عليك ببساطة استدعاء Complete على النطاق من أجل ارتكاب المعاملة عندما يتم إنهاء النطاق.

ومع ذلك ، يكون TransactionScope عادة اختيارًا أفضل لأنه يسمح لك بتعشيق المكالمات مع الطرق الأخرى التي قد تتطلب معاملة دون الحاجة إلى تمرير حالة المعاملة.

عند استدعاء BeginTransaction على كائن DbConnection ، يجب تمرير كائن المعاملة حول إذا كنت ترغب في تنفيذ عمليات أخرى في نفس المعاملة ولكن في أسلوب مختلف.

مع TransactionScope ، طالما أن النطاق موجود ، فإنه سيقوم بمعالجة كل ما يتم تسجيله باستخدام Transaction الحالية على مؤشر الترابط ، مما يجعل نظافة التعليمات البرمجية ، وأكثر قابلية للإصلاح.

علاوة على ذلك ، لديك فائدة إضافية تتمثل في القدرة على استخدام الموارد الأخرى التي يمكن أن تشارك في المعاملات ، وليس فقط الاتصال بقاعدة البيانات.

تجدر الإشارة إلى أنه في الحالات التي تحتاج فيها إلى الحصول على أقصى استفادة من اتصالاتك وعمليات قاعدة البيانات ، قد لا ترغب في استخدام TransactionScope ؛ حتى ضد قاعدة بيانات واحدة ، يمكنك تشغيل إمكانية "منسق المعاملات الموزعة" قيد الاستخدام وإجراء المعاملة قيد المعاملة الموزعة (حتى لاتصال قاعدة بيانات واحد).

في هذه الحالات ، بينما تقوم بتخفيض التصميم الخاص بك ، قد ترغب في النظر في تمرير عملية اتصال خاصة حولها.

أو ، إذا كنت تعلم أنك ستستخدم موردًا واحدًا بشكل دائم (وعلى نفس سلسلة المحادثات) ، فقد تحتاج إلى إنشاء فصل يحسب فيه المرجع اتصالك / معاملتك.

يمكنك إنشاء فئة في البناء ، يخلق المورد الخاص بك / الزيادات العد. سيقوم أيضاً بتطبيق IDisposable (حيث تقوم بتقليص / تحرير / الالتزام / الإيقاف عندما يكون العدد صفر) ، وتخزين العدد في متغير يحتوي على ThreadStaticAttribute المطبق عليه.

يسمح لك ذلك بفصل إدارة المعاملات عن رمز المنطق ، ولا تزال تحتفظ بمورد فريد إلى حد ما بكفاءة (بدلاً من التصعيد إلى معاملة موزعة).


اختلاف كبير واحد (درس الدرس بالطريقة الصعبة) - يستخدم TransactionScope MS DTC لإدارة المعاملات.

إذا كان التطبيق الخاص بك لإدارة معاملة قاعدة البيانات فقط ، ولا يتم تضمين أية خدمات أو مكالمات عن بُعد ، يمكنك تخطي المشكلات المحتملة المتعلقة بـ MS DTC باستخدام المعاملة الأصلية في قواعد البيانات (DbTransactions).


استخدم هذا:

from c in dc.Organization
where SqlMethods.Like(c.Hierarchy, "%/12/%")
select *;




c# linq linq-to-sql transactions