İşlemi C # Kodunda ve saklı yordamda işlememiz gerekiyor mu


14

Gerçekten her iki tarafta da veritabanı deposu işleminin yanı sıra c # işlem işlemeyi gerektiriyor mu

C #:

Using(transaction with transaction scope)
{
     Execute stored proc;
     Transaction. Complete;
}

SQL saklı yordamı:

Create process
As
Begin try
    Begin transaction
    Commit
End try
Begin catch
    Rollback
End catch

Yanıtlar:


20

İlk olarak , tüm prosedürlerinizde her zaman uygun işlem yönetimine sahip olmalısınız, böylece uygulama koduyla, başka bir yordamla, ayrı bir ad hoc sorguda, bir SQL Agent işiyle veya başka bir yolla çağrılmaları önemli değildir. . Ama herhangi bir değişiklik yapmaz tek DML ifadeleri veya kod, etmez ihtiyaç açık bir İşlem. Yani, ne tavsiye ediyorum:

  • Hataların düzgün bir şekilde kabarması için daima TRY / CATCH yapısına sahip olun
  • İsteğe bağlı olarak, birden fazla DML ifadeniz varsa (tek bir ifade kendi başına bir işlem olduğu için) aşağıdaki koda 3 İşlem işleme parçasını ekleyin. Ancak, özellikle gerekli olmayan bazı ek kodlar eklemek dışında, tutarlı bir şablona sahip olmayı tercih ederseniz, İşlemle ilgili 3 IF bloğunda tutmak zarar vermez. Ancak bu durumda , yalnızca SELECT (yalnızca salt okunur) işlemlerde 3 İşlemle ilgili IF bloğunun tutulmamasını öneririm .

2 veya daha fazla DML ifadesi yaparken , aşağıdakilerin satırları boyunca bir şey kullanmanız gerekir (bu, tutarlı olmasını tercih ederse tek DML işlemleri için de yapılabilir):

CREATE PROCEDURE [SchemaName].[ProcedureName]
(
    @Param  DataType
    ...
)
AS
SET NOCOUNT ON;
DECLARE @InNestedTransaction BIT;

BEGIN TRY

    IF (@@TRANCOUNT = 0)
    BEGIN
        SET @InNestedTransaction = 0;
        BEGIN TRAN; -- only start a transaction if not already in one
    END;
    ELSE
    BEGIN
        SET @InNestedTransaction = 1;
    END;

    -- { 2 or more DML statements (i.e. INSERT / UPDATE / DELETE) }

    IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0)
    BEGIN
        COMMIT;
    END;

END TRY
BEGIN CATCH

    IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0)
    BEGIN
        ROLLBACK;
    END;

    DECLARE @ErrorMessage   NVARCHAR(4000) = ERROR_MESSAGE(),
            @ErrorState     INT = ERROR_STATE(),
            @ErrorSeverity  INT = ERROR_SEVERITY();

    -- optionally concatenate ERROR_NUMBER() and/or ERROR_LINE() into @ErrorMessage

    RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
    RETURN;

END CATCH;

Yalnızca 1 DML ifadesi veya yalnızca bir SELECT yaparken, aşağıdakilerden kaçabilirsiniz:

CREATE PROCEDURE [SchemaName].[ProcedureName]
(
    @Param  DataType
    ...
)
AS
SET NOCOUNT ON;

BEGIN TRY

    -- { 0 or 1 DML statements (i.e. INSERT / UPDATE / DELETE) }

END TRY
BEGIN CATCH

    DECLARE @ErrorMessage   NVARCHAR(4000) = ERROR_MESSAGE(),
            @ErrorState     INT = ERROR_STATE(),
            @ErrorSeverity  INT = ERROR_SEVERITY();

    -- optionally concatenate ERROR_NUMBER() and/or ERROR_LINE() into @ErrorMessage

    RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
    RETURN;

END CATCH;

İkincisi , uygulama katmanındaki işlemi yalnızca 1'den fazla sorgu / saklı yordamı yürütmeniz ve hepsinin bir atomik işlem halinde gruplandırılması gerekiyorsa işlemeniz gerekir. Tek bir SqlCommand.Execute___işlemin sadece bir deneme / yakalamada olması gerekir, ancak bir İşlemde olması gerekmez.

Ancak, yalnızca tek bir arama yaparken uygulama katmanında bir İşlem yapmak acıyor mu? MSDTC (Microsoft Dağıtılmış İşlem Düzenleyicisi) gerektiriyorsa, açıkça gerekli olmadığında uygulama katmanında bunu yapmak sistemde biraz daha ağırdır. Şahsen, artık yetim işlemler için potansiyeli azaltmadığı sürece kesinlikle uygulama katmanı tabanlı işlemlerden kaçınmayı tercih ediyorum (taahhüt veya geri alma işleminden önce uygulama kodunda bir sorun varsa). Ayrıca, bazı durumlarda hata ayıklamayı biraz daha zorlaştırdığını da buldum. Ancak söyleniyor, teknik olarak yanlış bir şey görmüyorum , aynı zamanda tek bir işlem yaparken uygulama katmanındaki işlemi de ele alıyorumaramak; Yine, tek bir DML deyimi kendi işlem ve gelmez ihtiyaç ya katmanında ele herhangi bir açık işlem.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.