مشاركة عبر


استخدام المعاملات في تجمع SQL في Azure Synapse

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

ما المتوقع

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

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

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

بمجرد تمكينها، يتم تنفيذ كافة المعاملات في قاعدة البيانات ضمن «عزل لقطة تنفيذ القراءة» ولن يُحترم إعداد لقطة عدم تنفيذ القراءة على مستوى الجلسة. تحقق من خيارات ALTER DATABASE SET (Transact-SQL) للتفاصيل.

حجم العملية

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

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

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

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

Gen2

DWU الحد الأقصى لكل توزيع (GB) عدد التوزيعات حجم العملية MAX (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) عدد التوزيعات حجم العملية MAX (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 القيام بذلك. إذا حدث خطأ داخل معاملة مجمع 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، يجب تغيير التعليمات البرمجية بشكل طفيف:

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_ * القيم كما هو متوقع.

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

دالة Error_Line()

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

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

استخدام THROW وعبارة RAISERROR

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

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

التقييدات

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

تظهر تلك الادعاءات كما يلي:

  • لا توجد معاملة موزعة
  • لا يسمح بأي معاملات متداخلة
  • لا يسمح بنقاط حفظ
  • لا توجد معاملات باسم
  • لا توجد معاملات محددة
  • لا يوجد دعم لـ DDL مثل CREATE TABLE داخل معاملة معرفة من المستخدم

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

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