سؤال

في مشروعنا الحالي ، نستخدم إطار عمل ADO.NET كطبقة بيانات للتطبيق. هناك بعض المهام التي تتطلب تشغيل معاملة لأن هناك الكثير من العمل الذي يجب القيام به في قاعدة البيانات. أنا أستخدم أ TransactionsCope لتطويق تلك المهام.

using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
    // Do something...
    transactionScope.Complete();
}

المشكلة بمجرد استخدامي TransactionsCope يحدث استثناء:

System.Data.EntityException: فشل المزود الأساسي في Open. ---> system.transactions.transactionAmerAgerCommunicationException: فشل التواصل مع مدير المعاملات الأساسية. ---> System.Runtime.InterOpservices.comexception (0x80004005): تم إرجاع خطأ Hresult E_Fail من مكالمة إلى مكون COM.

يبدو أن هذا الخطأ يجب أن يفعل شيئًا مع MSDTC (منسق المعاملات الموزعة Microsoft). عندما أقوم بتغيير تكوين الأمان لـ MSDTC ، يتم طرح استثناء آخر:

System.Data.EntityException: فشل المزود الأساسي في Open. ---> system.transactions.transactionActionagerCommunicationException: تم تعطيل الوصول إلى الشبكة لمدير المعاملات الموزع (MSDTC). يرجى تمكين DTC للوصول إلى الشبكة في تكوين الأمان لـ MSDTC باستخدام الأداة الإدارية لخدمات المكونات.

ومع ذلك تم تكوين MSDTC ، TransactionsCope سوف يسبب خطأ. هل يعرف أحد ما الخطأ هنا؟

هل كانت مفيدة؟

المحلول 8

حسنًا ، يبدو أنه يعمل عندما أقوم بتغيير TransactionsCopeOption يقمع":

using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Suppress))
{
    ...
}

هل يعرف الجميع لماذا؟

نصائح أخرى

بشكل افتراضي ، تعطيل MSDTC للوصول إلى الشبكة. للحصول عليها ، يجب عليك الذهاب إلى

لوحة التحكم-> الأدوات الإدارية-> خدمات المكونات-> Serivces Componn

وتحقق من مربعات الاختيار التالية الوصول إلى الشبكة DTC ، والسماح للداخل ، والسماح للخارج. يجب اختيار المصادقة وفقًا لبيئةكم. قد ترغب أيضًا في إلقاء نظرة على dtcping أداة لتصحيح المعاملات الموزعة. لإعطائك اختصار - قد تحتاج إلى تعديل السجل:

hklm software policies microsoft windows nt rpcrestrictremoteclients = 0 hklm software policies microsoft windows nt rpcenableauthepresolution = 1

للحصول على كل شيء وتشغيل.

نعم ، إنه يعمل باستخدام DUBRESS ، لأنك تخبرها بتجاهل المعاملة المحيطة أو تجاهلها وإنشاء معاملة محلية جديدة. نظرًا لأن المعاملة محلية ، فهي ليست معاملة موزعة ، لذا فهي لا تستخدم MSDTC ، ولكن ربما يجب ألا تستخدم القمع ويجب استخدامه المطلوبة بدلاً من ذلك.

هذا يعني أنه يؤدي إلى قمع أي معاملة قد تكون سارية المفعول حاليًا عند إدخال كتلة التعليمات البرمجية الخاصة بك ، وبالتالي فإن أي تحديثات تجعل الرمز الخاص بك لن تراجع إذا قررت المعاملة الخارجية "المحيطة" التراجع.

هذه هي المقالة التي استخدمناها في حل مشكلة مشابهة:

استكشاف الأخطاء وإصلاحها مع MSDTC

هذا في الأساس إضافة إلى نيكولاي آر إجابه. لقد غطى بالفعل بعض الاقتراحات المدرجة في المقالة.

ملاحظة: المقالة جزء من وثائق BizTalk ، ولكن يمكن أن تنطبق على أي شيء باستخدام MSDTC.

"إذا كنت تستخدم إطار عمل الكيان مع المعاملات ، فإن إطار الكيان يفتح تلقائيًا ويغلق اتصالًا مع كل مكالمة قاعدة بيانات. لذلك عند استخدام المعاملات ، فأنت تحاول نشر معاملة على اتصالات متعددة. هذا يرفع إلى MSDTC."

يمكنك تمرير سياق قاعدة البيانات الخاصة بك إلى فئة أو وظيفة Callee في معاملتك.

ربما هذا هو إجابتك: خطأ MSSQL "فشل المزود الأساسي في Open"

يعد قمع المعاملة مفيدًا إذا كنت ترغب في تشغيل بعض التعليمات البرمجية التي قد تفشل ، لكنك لا ترغب في إحباط المعاملة بسبب فشل ذلك.

السؤال الذي تحتاج إلى طرحه على نفسك هو ما يلي: هل يمكنك الوصول إلى أكثر من مورد متين واحد في TransactionsCope؟ أعني ، هل تفتح الاتصالات لأكثر من 1 ديسيبل؟

هذا سؤال مهم حيث سيتم تصعيد المعاملة نحو DTC إذا قمت بالوصول إلى أكثر من مورد دائم.

يتم تجنيد اثنين على الأقل من الموارد الدائمة التي تدعم الإخطارات ذات الطور الواحد في المعاملة. على سبيل المثال ، لا يتسبب تجنيد اتصال واحد مع معاملة في الترويج. ومع ذلك ، كلما فتحت اتصالًا ثانيًا بقاعدة بيانات تسبب في تجنيد قاعدة البيانات ، تكتشف System.Transactors البنية التحتية أن هذا هو المورد الثاني المتين في المعاملة ، وتصاعدها إلى معاملة MSDTC.مصدر: MSDN

إذا كان هذا هو الحال ، فيمكنك حل مشكلتك عن طريق تداخل معاملاتك بشكل صحيح ، على سبيل المثال:

//Create rootScope
using(TransactionScope rootScope = new TransactionScope()) 
{ 
    using(TransactionScope scope2 = new 
    TransactionScope(TransactionScopeOption.Required)) 
    {
         //Do work on DB1
         ...

         //Complete this ambient transaction
         scope2.Complete();
    } 

    using(TransactionScope scope3 = new 
    TransactionScope(TransactionScopeOption.Required)) 
    {
         //Do work on DB2
         ...

         //Complete this ambient transaction
         scope3.Complete();
    } 

    //Complete rootScope
    //The whole transaction will only be committed if you call 
    //Complete on the rootScope
    rootScope.Complete();

}

يمكنك العثور على مزيد من المعلومات حول المعاملات ، وكيف يعمل التعشيش ، ... MSDN.

آمل أن تساعد هذه الإجابة الناس في المستقبل.

إذا لم يتم تشغيل خدمة منسق المعاملات الموزعة ، فلن يتمكن Entity Framework بقاعدة البيانات. افتح وابدأ منسق المعاملات الموزعة

الخدمات -> منسق المعاملات الموزعة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top