المعاملات الموزعة لقواعد البيانات غير المتجانسة في MS .NET

سُئلت مؤخرًا في مقابلة عما إذا كنت قد عملت مع المعاملات الموزعة ، بمعنى أنني اضطررت إلى إدخال / تحديث هذه السجلات ، شريطة:

  1. معاملة واحدة.
  2. يمكن أن يكون هناك العديد من قواعد البيانات المختلفة مثل Oracle و MS SQL Server و PostgreSQL.
  3. يمكن أن تكون الاستجابة لعملية CRUD كبيرة.
  4. تسلسل الإدراج غير مهم.

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

قبل أن أصف حلا لي ، لنتذكر كيف يتم تنفيذ المعاملات الموزعة النموذجية باستخدام منصة Microsoft كمثال.

الخيار رقم 1. تطبيق C ++ وبرنامج تشغيل ODBC (المملوك من قبل منسق المعاملات الموزعة لـ Microsoft (MSDTC) لـ SQL Server

) يسمح منسق المعاملات الموزعة لـ Microsoft (MSDTC) للتطبيقات بتوسيع المعاملات أو توزيعها عبر مثيلين أو أكثر من مثيلات SQL Server. تعمل المعاملة الموزعة حتى إذا كانت هناك حالتان موجودتان على أجهزة كمبيوتر مختلفة.

يعمل MSDTC محليًا فقط لـ Microsoft SQL Server ولا يتوفر لخدمة قاعدة بيانات سحابة Microsoft Azure SQL.

يتم استدعاء MSDTC بواسطة برنامج تشغيل عميل SQL Server الأصلي لاتصال قاعدة البيانات المفتوح (ODBC) عندما يقوم برنامج C ++ بإدارة معاملة موزعة. يحتوي برنامج تشغيل ODBC للعميل الأصلي على مدير معاملة متوافق مع XA Open Distributed Transaction Processing (DTP). مطلوب هذا الامتثال من قبل MSDTC. بشكل عام ، يتم إرسال كافة أوامر إدارة المعاملات من خلال برنامج تشغيل ODBC هذا للعميل الأصلي. التسلسل كما يلي:

يبدأ تطبيق ODBC لعميل C ++ الأصلي معاملة عن طريق استدعاء SQLSetConnectAttr مع تعطيل الالتزام التلقائي.
يقوم التطبيق بتحديث بعض البيانات الموجودة على SQL Server X على الكمبيوتر A.
يقوم التطبيق بتحديث بعض البيانات على SQL Server X على الكمبيوتر B.
إذا فشل التحديث على SQL Server Y ، فسيتم إرجاع جميع التحديثات غير الملتزم بها في كل من مثيلات SQL Server.
وأخيرًا ، يكمل التطبيق المعاملة عن طريق استدعاء SQLEndTran (1) باستخدام خيار SQL_COMMIT أو SQL_ROLLBACK.

(1) يمكن استدعاء MS DTC بدون ODBC. في هذه الحالة ، يصبح MS DTC مدير معاملات ، ولم يعد التطبيق يستخدم SQLEndTran.

معاملة موزعة واحدة فقط.

افترض أن تطبيق ODBC الخاص بك لعميل C ++ مسجل في معاملة موزعة. ثم يتم إضافة الطلب إلى المعاملة الموزعة الثانية. في هذه الحالة ، يترك برنامج تشغيل ODBC عميل SQL Server الأصلي المعاملة الموزعة الأصلية ويتم تضمينه في المعاملة الموزعة الجديدة.

اقرأ المزيد عن MSDTC هنا..

الخيار رقم 2. تطبيق C # ، كبديل لقاعدة بيانات SQL في سحابة Azur ،

MSDTC غير مدعوم لقاعدة بيانات Azure SQL أو مستودع بيانات Azure SQL.

ومع ذلك ، يمكنك إنشاء معاملة موزعة لقاعدة بيانات SQL إذا كان برنامج C # الخاص بك يستخدم فئة .NET System.Transactions.TransactionScope.

يوضح المثال التالي كيفية استخدام فئة TransactionScope لتعريف كتلة التعليمات البرمجية للمشاركة في المعاملة.

static public int CreateTransactionScope(
    string connectString1, string connectString2,
    string commandText1, string commandText2)
{
    //        StringWriter   
   // .
    int returnValue = 0;
    System.IO.StringWriter writer = new System.IO.StringWriter();

    try
    {
        //  TransactionScope   , 
        //            
        //  .
        using (TransactionScope scope = new TransactionScope())
        {
            using (SqlConnection connection1 = new SqlConnection(connectString1))
            {
                //      
                // TransactionScope   .
                connection1.Open();

                //   SqlCommand    .
                SqlCommand command1 = new SqlCommand(commandText1, connection1);
                returnValue = command1.ExecuteNonQuery();
                writer.WriteLine("   command1: {0}", returnValue);

                //      ,  ,  
                //  command1  .  
                //    using  connection2   connection1, 
                //         connection2 
                //      .   
                using (SqlConnection connection2 = new SqlConnection(connectString2))
                {
                    //       
                    //   connection2 .
                    connection2.Open();

                    //      .
                    returnValue = 0;
                    SqlCommand command2 = new SqlCommand(commandText2, connection2);
                    returnValue = command2.ExecuteNonQuery();
                    writer.WriteLine("    command2: {0}", returnValue);
                }
            } 
            scope.Complete();
        }
    }
    catch (TransactionAbortedException ex)
    {
        writer.WriteLine("   : {0}", ex.Message);
    }

    Console.WriteLine(writer.ToString());

    return returnValue;
}

الخيار رقم 3. تطبيقات C # و Entity Framework الأساسية للمعاملات الموزعة.

بشكل افتراضي ، إذا كان موفر قاعدة البيانات يدعم المعاملات ، يتم تطبيق كافة التغييرات في استدعاء واحد لـ SaveChanges () على المعاملة. إذا لم يتم تنفيذ أي من التغييرات ، يتم إرجاع المعاملة ، ولا يتم تطبيق أي من التغييرات على قاعدة البيانات. وهذا يعني أن SaveChanges () مضمون لإكماله بنجاح أو ترك قاعدة البيانات دون تغيير في حالة حدوث خطأ.

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

يمكنك استخدام DbContext.Database APIلبدء المعاملات والالتزام بها واسترجاعها. يوضح المثال التالي عمليتي SaveChanges () واستعلام LINQ الذي تم تنفيذه في معاملة واحدة.

لا يدعم جميع موفري قواعد البيانات المعاملات. قد يصدر أو لا يقوم بعض الموفرين بإصدار معاملات عند استدعاء API للمعاملات.

using (var context = new BloggingContext())
{
    using (var transaction = context.Database.BeginTransaction())
    {
        try
        {
            context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
            context.SaveChanges();

            context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/visualstudio" });
            context.SaveChanges();

            var blogs = context.Blogs
                .OrderBy(b => b.Url)
                .ToList();

           transaction.Commit();
        }
        catch (Exception)
        {
             
        }
    }
}

إذا كنت تستخدم EF Core في .NET Framework ، فإن تنفيذ System.Transactions هناك يدعم المعاملات الموزعة.

كما ترى من الوثائق الموجودة في إطار النظام الأساسي وخط منتجات Microsoft ، فإن المعاملات الموزعة ليست مشكلة: MSDTC ، السحابة نفسها تتحمل الأخطاء ، مجموعة من ADO .NET + EF Core للمجموعات الغريبة (اقرأ هنا ).

كيف تساعدنا مراجعة المعاملات على منصة Microsoft على حل المشكلة؟ بسيطة للغاية ، هناك فهم واضح أنه ببساطة لا توجد مجموعة أدوات قياسية لتنفيذ معاملة موزعة عبر قواعد البيانات غير المتجانسة في تطبيق .NET.

وإذا كان الأمر كذلك ، فإننا نصنع منسق المعاملات الموزعة المنسق محليًا (CRT) الخاص بنا.

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

لذلك ، نحتاج إلى آلية مختلفة قليلاً. فيما يلي نهج عام لتطوير MCT.



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

  • الذرية
  • منطق
  • عزل
  • طول العمر

- قد يكون جزءًا من التطبيق الذي قام المستخدم من خلاله بإنشاء سجل ، أو قد يكون تطبيقًا منفصلاً تمامًا في شكل خدمة نظام. قد يحتوي على عملية فرعية خاصة تولد معاملات في تجمع للتنفيذ عند حدوث انقطاع في الطاقة (غير موضح في الرسم التخطيطي). يمكن إضافة قواعد العمل الخاصة بتحويل (تعيين) البيانات المصدر التي تم إنشاؤها بواسطة المستخدم لقواعد البيانات ذات الصلة بشكل ديناميكي وتكوينها عبر تنسيق XML / JSON وتخزينها في مجلد التطبيق المحلي أو في سجل المعاملات (كخيار). وفقًا لذلك ، في هذه الحالة ، يُنصح بتوحيد التحويل إلى قواعد البيانات ذات الصلة على مستوى الشفرة من خلال تطبيق نموذجية المحولات في شكل مكتبات DLL. (ونعم ، يشير SRT إلى الوصول المباشر إلى قاعدة البيانات دون مشاركة Web API.)

وبالتالي ، يمكن تنفيذ SRT في شكل بسيط بنجاح كجزء من التطبيق ، أو كحل منفصل وقابل للتخصيص ومستقل (أيهما أفضل).

مرة أخرى ، سأوضح أن المعاملة الموزعة هي ، بحكم تعريفها ، تخزين للمعلومات لمرة واحدة دون تغييرها ، ولكن مع القدرة على تعيين قواعد بيانات مختلفة في مخططات البيانات. لذلك إذا كنت بحاجة إلى تسجيل البيانات في قواعد أخرى ، على سبيل المثال ، في وزارة الشؤون الداخلية و FSB وشركات التأمين ، عند تسجيل الحوادث في غرفة الطوارئ في المستشفى (جرح رصاصة) ، فإن هذا النهج سيساعدك بالتأكيد. يمكن أن تعمل الآلية نفسها بشكل مثالي في المؤسسات المالية.

آمل أن يكون هذا النهج مثيرًا للاهتمام لك ، اكتب رأيك حوله ، الزملاء والأصدقاء!

All Articles