Use transactions in a SQL pool in Azure Synapse

تلميح

Microsoft Fabric Data Warehouse هو مستودع علائقي على نطاق مؤسسي قائم على أساس بحيرة البيانات، مع بنية جاهزة للمستقبل، وذكاء اصطناعي مدمج، وميزات جديدة. إذا كنت جديدا في مستودع البيانات، ابدأ ب Fabric Data Warehouse. يمكن لأحمال عمل تجمع SQL المخصصة الحالية الترقية إلى Fabric للوصول إلى قدرات جديدة في علوم البيانات، والتحليلات اللحظية، والتقارير.

تتضمن هذه المقالة نصائح لتنفيذ المعاملات وتطوير الحلول في تجمع SQL.

ما يمكن توقعه

كما هو متوقع، تجمع SQL يدعم المعاملات كجزء من عبء عمل مستودع البيانات. ومع ذلك، لضمان الحفاظ على تجمع SQL على نطاق واسع، هناك بعض الميزات محدودة مقارنة ب SQL Server. تسلط هذه المقالة الضوء على الفروقات.

مستويات عزل المعاملات

تجمع SQL ينفذ معاملات ACID. مستوى العزل في دعم المعاملات يكون افتراضيا على READ غير ملتزم. يمكنك تغييره إلى READ COMMITTED SNAPSHOT ISOLATION عن طريق تفعيل خيار قاعدة البيانات READ_COMMITTED_SNAPSHOT لمجموعة SQL الخاصة بالمستخدم عند الاتصال بقاعدة البيانات الرئيسية.

بمجرد تفعيلها، يتم تنفيذ جميع المعاملات في هذه قاعدة البيانات تحت عزل لقطة القراءة المرتزم ولن يتم قبول تعيين READ غير ملتزم على مستوى الجلسة. تحقق من خيارات مجموعة قواعد بيانات alter (Transact-SQL) لمزيد من التفاصيل.

حجم المعاملة

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

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

في الجدول التالي، تم وضع افتراضين:

  • حدث توزيع متساو للبيانات
  • متوسط طول الصف هو 250 بايت

Gen2

DWU الحد الأقصى لكل توزيع (GB) عدد التوزيعات الحد الأقصى لحجم المعاملات (GB) # الصفوف لكل توزيع الحد الأقصى للصفوف لكل معاملة
DW100c 1 60 60 4,000,000 240,000,000
DW200c 1.5 60 90 6,000,000 360,000,000
DW300c 2.25 60 135 9,000,000 540,000,000
DW400c 3 60 180 12,000,000 720,000,000
DW500c 3.75 60 225 15,000,000 900,000,000
DW1000c 7.5 60 450 30,000,000 1,800,000,000
DW1500c 11.25 60 675 45,000,000 2,700,000,000
DW2000c 15 60 900 60,000,000 3,600,000,000
DW2500c 18.75 60 1125 75,000,000 4,500,000,000
DW3000c 22.5 60 1,350 90,000,000 5,400,000,000
DW5000c 37.5 60 2,250 150,000,000 9,000,000,000
DW6000c 45 60 2,700 180,000,000 10,800,000,000
DW7500c 56.25 60 3,375 225,000,000 13,500,000,000
DW10000c 75 60 4,500 300,000,000 18,000,000,000
DW15000c 112.5 60 6,750 450,000,000 27,000,000,000
DW30000c 225 60 13,500 900,000,000 54,000,000,000

Gen1

DWU الحد الأقصى لكل توزيع (GB) عدد التوزيعات الحد الأقصى لحجم المعاملات (GB) # الصفوف لكل توزيع الحد الأقصى للصفوف لكل معاملة
DW100 1 60 60 4,000,000 240,000,000
DW200 1.5 60 90 6,000,000 360,000,000
DW300 2.25 60 135 9,000,000 540,000,000
DW400 3 60 180 12,000,000 720,000,000
DW500 3.75 60 225 15,000,000 900,000,000
DW600 4.5 60 270 18,000,000 1,080,000,000
DW1000 7.5 60 450 30,000,000 1,800,000,000
DW1200 9 60 540 36,000,000 2,160,000,000
DW1500 11.25 60 675 45,000,000 2,700,000,000
DW2000 15 60 900 60,000,000 3,600,000,000
DW3000 22.5 60 1,350 90,000,000 5,400,000,000
DW6000 45 60 2,700 180,000,000 10,800,000,000

يتم تطبيق حد حجم المعاملة لكل معاملة أو عملية. لا يطبق على جميع المعاملات المتزامنة. لذلك يسمح لكل معاملة بكتابة هذا الكم من البيانات في السجل.

لتحسين وتقليل كمية البيانات المكتوبة إلى السجل، يرجى الرجوع إلى مقالة أفضل ممارسات المعاملات .

تحذير

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

حالة المعاملة

تستخدم مجموعة SQL دالة XACT_STATE() للإبلاغ عن معاملة فاشلة باستخدام القيمة -2. تعني هذه القيمة أن المعاملة فشلت وتم تمييزها للتراجع فقط.

‏‫ملاحظة‬

استخدام -2 من قبل دالة XACT_STATE للدلالة على معاملة فاشلة يمثل سلوكا مختلفا عن SQL Server. يستخدم SQL Server القيمة -1 لتمثيل معاملة غير قابلة للالتزام. يمكن ل SQL Server تحمل بعض الأخطاء داخل المعاملة دون الحاجة إلى تصنيفها على أنها غير قابلة للالتزام. على سبيل المثال، SELECT 1/0 قد يسبب خطأ لكنه لا يجبر المعاملة على الدخول في حالة غير قابلة للالتزام.

كما يسمح SQL Server بالقراءة في المعاملة غير القابلة للالتزام. ومع ذلك، لا يسمح لك SQL Pool بذلك. إذا حدث خطأ داخل معاملة تجمع SQL، فسيدخل تلقائيا الحالة -2 ولن تتمكن من إصدار أي بيانات محددة أخرى حتى يتم التراجع عن البيان.

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

على سبيل المثال، في SQL Server، قد ترى معاملة تبدو كما يلي:

SET NOCOUNT ON;
DECLARE @xact_state smallint = 0;

BEGIN TRAN
    BEGIN TRY
        DECLARE @i INT;
        SET     @i = CONVERT(INT,'ABC');
    END TRY
    BEGIN CATCH
        SET @xact_state = XACT_STATE();

        SELECT  ERROR_NUMBER()    AS ErrNumber
        ,       ERROR_SEVERITY()  AS ErrSeverity
        ,       ERROR_STATE()     AS ErrState
        ,       ERROR_PROCEDURE() AS ErrProcedure
        ,       ERROR_MESSAGE()   AS ErrMessage
        ;

        IF @@TRANCOUNT > 0
        BEGIN
            ROLLBACK TRAN;
            PRINT 'ROLLBACK';
        END

    END CATCH;

IF @@TRANCOUNT >0
BEGIN
    PRINT 'COMMIT';
    COMMIT TRAN;
END

SELECT @xact_state AS TransactionState;

الكود السابق يعطي رسالة الخطأ التالية:

الجنرال 111233، المستوى 16، الولاية 1، الخط 1 111233؛ تم إلغاء المعاملة الحالية، وتم التراجع عن أي تغييرات معلقة. سبب هذه المشكلة هو أن المعاملة في حالة التراجع فقط لا يتم إرجاعها صراحة قبل بيان DDL أو DML أو SELECT.

لن تحصل على مخرج دوال ERROR_*.

في SQL Pool، يحتاج الكود إلى تعديل بسيط:

SET NOCOUNT ON;
DECLARE @xact_state smallint = 0;

BEGIN TRAN
    BEGIN TRY
        DECLARE @i INT;
        SET     @i = CONVERT(INT,'ABC');
    END TRY
    BEGIN CATCH
        SET @xact_state = XACT_STATE();

        IF @@TRANCOUNT > 0
        BEGIN
            ROLLBACK TRAN;
            PRINT 'ROLLBACK';
        END

        SELECT  ERROR_NUMBER()    AS ErrNumber
        ,       ERROR_SEVERITY()  AS ErrSeverity
        ,       ERROR_STATE()     AS ErrState
        ,       ERROR_PROCEDURE() AS ErrProcedure
        ,       ERROR_MESSAGE()   AS ErrMessage
        ;
    END CATCH;

IF @@TRANCOUNT >0
BEGIN
    PRINT 'COMMIT';
    COMMIT TRAN;
END

SELECT @xact_state AS TransactionState;

السلوك المتوقع الآن يلاحظ. يتم إدارة الخطأ في المعاملة وتوفر دوال ERROR_* القيم كما هو متوقع.

كل ما تغير هو أن التراجع عن المعاملة كان يجب أن يحدث قبل قراءة معلومات الخطأ في كتلة CATCH.

دالة Error_Line()

ومن الجدير بالذكر أيضا أن مجموعة SQL لا تنفذ أو تدعم دالة ERROR_LINE(). إذا كان لديك هذا في الكود الخاص بك، عليك إزالته ليكون متوافقا مع مجموعة SQL.

استخدم تسميات الاستعلام في كودك بدلا من ذلك لتنفيذ الوظائف المكافئة. لمزيد من التفاصيل، راجع مقال LABEL .

استخدام THROM و RAISERROR

THROW هو التطبيق الأحدث لجمع الاستثناءات في تجمع SQL لكن RAISERROR مدعوم أيضا. هناك بعض الاختلافات التي تستحق الانتباه مع ذلك.

  • لا يمكن أن تكون أرقام رسائل الخطأ المعرفة من قبل المستخدم في نطاق 100,000 - 150,000 ل THROW
  • رسائل خطأ RAISERROR ثابتة عند 50,000
  • استخدام sys.messages غير مدعوم

القيود

لدى SQL Pool بعض القيود الأخرى المتعلقة بالمعاملات.

وهي كما يلي:

  • لا توجد معاملات موزعة
  • لا يسمح بالمعاملات المتداخلة
  • لا يسمح بنقاط الحفظ
  • لا توجد معاملات مسماة
  • لا توجد معاملات معلمة
  • لا يوجد دعم ل DDL مثل إنشاء جدول داخل معاملة يحددها المستخدم

الخطوات التالية

لمعرفة المزيد حول تحسين المعاملات، راجع أفضل ممارسات المعاملات. للتعرف على أفضل ممارسات تجمع SQL الأخرى، راجع أفضل ممارسات تجمع SQL.