Aracılığıyla paylaş


Zarar iletisi işleme

Bu konuda Hizmet Aracısı'ı kullanan bir uygulama için bir şekilde tanımlayan algılamak bir zehirli ileti ve Kaldır üzerinde otomatik poison güvenmek zorunda kalmadan sıradan ileti algılamak iyon iletisi gönderir.

Hizmet Aracısı otomatik zehirli ileti algılama sağlar.Sıradaki iletileri alan bir işlem, beş kez geri alır, otomatik zehirli ileti algılama, KAPALı sıra durumunu ayarlar.Bu özellik, uygulamanın edemiyor Geri dönülemez hatalarına karşı güvenlik amacıyla sağlar algılamak programsal olarak.Ancak, normal işlem için bu özelliği bir uygulama güvenmemelisiniz.Sıranın otomatik zehirli ileti algılama vermiyor olduğundan, zehirli ileti kaldırılıncaya kadar bu özellik etkin uygulama için tüm işlem durur.Bunun yerine, bir uygulama zarar iletiler, uygulama mantığını bir parçası olarak algılayacak ve denemeniz gerekir.

Bu bölümde özetlenen strateji, belirli bir kaç kez başarısız olursa ileti kaldırılması gerektiğini varsaymaktadır.Bu varsayımı birçok uygulama için geçerlidir.Ancak bu stratejiyi uygulamanızda kullanmadan önce aşağıdaki soruları kullanın:

  • Başarısızlık sayısı, uygulamanız için güvenilir midir?Uygulamanıza bağlı olarak, normal olarak iletileri için saat saat başarısız olabilir.Örneğin, bir sipariş giriş uygulaması sipariş işleyen hizmet daha yeni bir müşteri kaydı ekler hizmet daha az işlem saat alabilir.Bu durum, hemen yeni bir müşteri için sipariş işlenemiyor normal olabilir.Uygulama gecikmesi için iletiye zararlı bir ileti olup olmadığını verirken hesabı gerekir.hizmet çeşitli hatalar ileti kaldırılmadan önce izin vermeniz gerekebilir.

  • Uygulamanızın hızla ve güvenle, hiçbir zaman başarısız, algılamak için bir iletinin içeriği denetleyebilirsiniz?Bu durumda, program ileti işlenemedi sayısı sayım daha iyi stratejiyi budur.Örneğin, bir çalışan adı veya çalışanın KIMLIK numarası içeren bir gider raporu işlenemiyor.Bu durum, program hemen bildiren bir hata ile işlenen yerine ileti işlemeye çalışırken ileti yanıtlarsa daha verimli olabilir.Diğer doğrulama göz önünde bulundurun.Örneğin, KIMLIK numarası varsa, ancak atanan numaraları (örneğin, negatif bir sayı) aralığının dışında kalan, uygulama görüşmeyi hemen sonlandırabilirsiniz.

  • Iletinin herhangi bir hatadan sonra kaldırmanız gerekir?Uygulama, her iletinin bir sınırlı ömrü bulunduğu yüksek hacimli iletileri işleme, hemen bir işlemin başarısız olmasına neden olan herhangi bir iletinin kaldırmak için en verimli olabilir.Örneğin, iletinin hedef hizmet ilerlemesini rapordan sağlarsa, iletinin işlemeden alma yapılıyor tarafından bir boş ilerleme durumu raporu atmak başlatan hizmet seçebilirsiniz.Bu durum, konuşmaya devam eder.

Uygulama bir zehirli ileti işleme biçimini karar verirken, aşağıdaki soruları göz önünde bulundurun:

  • Başarısızlık ve iletinin içeriği uygulamanızın oturum açması gerekir?Çoğu durumda, bu gerekli değildir.Ancak, bazı uygulamalar, iletinin içeriğini koruma uygun olabilir.

  • Başarısızlık hakkında diğer bilgiler, uygulamanızın oturum açması gerekir?Bazı durumlarda, görüşmeyi hakkındaki diğer bilgileri izlemek isteyebilirsiniz.Örneğin, katalog görünümünü kullanabilirsiniz. sys.conversation_endpoints zehirli ileti oluşturan bir uzak aracısı örnek tanımlamak için.

  • hizmet anlaşma görüşmeyi kapatmanıza gerek kalmadan bir hatayı göstermek bir uygulama izin vermelidir veya bir hata ile konuşma, uygulama son gerekir?zehirli ileti alma için birçok hizmet, anlaşma'de açıklanan Görev tamamlanamıyor anlamına gelir.Bu durum, uygulama, görüşmeyi bir hata ile sona erdirir.Bazı durumlardaysa, görüşmeyi tek bir ileti başarısız olsa bile devam mümkün olabilir.Örneğin, bir ambar kat stok veri alan bir hizmet zaman zaman bir bilinmeyen parça numarasını içeren bir ileti alabilirsiniz.Görüşmeyi bitiş yerine hizmet iletiyi daha sonra incelemek bir işleç için ayrı bir tablo kaydedin.

Örnek: zehirli ileti algılanıyor

Bu Transact-SQL Örneğin, zararlı ileti işleme mantığını içeren, basit, durum bilgisi olmayan bir hizmet gösterir. saklı yordam bir ileti aldığında, önce yordamı hareket kaydeder.Yordamı, ileti işlenemiyor, hareketi kaydetme için Yedekleme yordamı zarlar gelin.Kısmi geri alma, iletinin Konuşma grubunda bir kilit tutulacağı devam ederken, sıraya ileti verir.Program, program konuşma grubu kilit basılı devam eder, çünkü riski olmadan başarısız iletileri başka bir sıra okuyucu ileti işleme listesini tutan bir tablo güncelleştirebilirsiniz.

Aþaðýdaki örnek, etkinleştirme tanýmlar saklı yordam uygulama için:

CREATE PROCEDURE ProcessExpenseReport
AS
BEGIN
  WHILE (1 = 1)
    BEGIN
      BEGIN TRANSACTION ;
      DECLARE @conversationHandle UNIQUEIDENTIFIER ;
      DECLARE @messageBody VARBINARY(MAX) ;
      DECLARE @messageTypeName NVARCHAR(256) ;

      SAVE TRANSACTION UndoReceive ;

        WAITFOR ( 
                  RECEIVE TOP(1)
                    @messageTypeName = message_type_name,
                    @messageBody = message_body,
                    @conversationHandle = conversation_handle
                    FROM ExpenseQueue
                 ), TIMEOUT 500 ;

        IF @@ROWCOUNT = 0
        BEGIN
          ROLLBACK TRANSACTION ;
          BREAK ;
        END ;

        -- Typical message processing loop: dispatch to a stored
        -- procedure based on the message type name.  End conversation
        -- with an error for unknown message types.

        -- Process expense report messages. If processing fails,
        -- roll back to the save point and track the failed message.

        IF (@messageTypeName =
              '//Adventure-Works.com/AccountsPayable/ExpenseReport')
          BEGIN
            DECLARE @expenseReport NVARCHAR(MAX) ;
            SET @expenseReport = CAST(@messageBody AS NVARCHAR(MAX)) ;
            EXEC AdventureWorks.dbo.AddExpenseReport
              @report = @expenseReport ;
            IF @@ERROR <> 0
             BEGIN
               ROLLBACK TRANSACTION UndoReceive ;
               EXEC TrackMessage @conversationHandle ;
             END ;
            ELSE
             BEGIN
               EXEC AdventureWorks.dbo.ClearMessageTracking
                 @conversationHandle ;
             END ;
           END ;
        ELSE

        -- For error messages and end dialog messages, end the
        -- conversation.

        IF (@messageTypeName =
              'https://schemas.microsoft.com/SQL/ServiceBroker/Error' OR
             @messageTypeName =
              'https://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
          BEGIN
            END CONVERSATION @conversationHandle ;
            EXEC dbo.ClearMessageTracking @conversationHandle ;
          END ;


         COMMIT TRANSACTION ;
    END ;
END ;

Saklı yordam TrackMessage başarısız ileti sayısını izler. Yordamı bir iletinin yeni bir sayaç ekler önce iletinin başarısız oldu değil tablo ExpenseServiceFailedMessages. Aksi halde yordam sayacı sayısı, ileti için denetler.Sayacı, önceden tanımlanmış bir sayıdan daha az olduğunda, yordamın sayacı artırır.Sayacı, önceden tanımlanmış sayı büyük olduğunda, yordamı bir hata ile konuşma sona erdirir ve bir konuşma için sayacı kaldırır tablo.

CREATE PROCEDURE TrackMessage
@conversationHandle uniqueidentifier
AS
BEGIN
  IF @conversationHandle IS NULL
    RETURN ;

  DECLARE @count INT ;
  SET @count = NULL ;
  SET @count = (SELECT count FROM dbo.ExpenseServiceFailedMessages
                  WHERE conversation_handle = @conversationHandle) ;

  IF @count IS NULL
    BEGIN
      INSERT INTO dbo.ExpenseServiceFailedMessages
        (count, conversation_handle)
        VALUES (1, @conversationHandle) ;
    END ;
  IF @count > 3
    BEGIN
      EXEC dbo.ClearMessageTracking @conversationHandle ;
      END CONVERSATION @conversationHandle
        WITH ERROR = 500
        DESCRIPTION = 'Unable to process message.' ;
    END ;
  ELSE
    BEGIN
      UPDATE dbo.ExpenseServiceFailedMessages
        SET count=count+1
        WHERE conversation_handle = @conversationHandle ;
    END ;
END ;
GO

Tablo tanımı ExpenseServiceFailedMessages yalnızca içeren bir conversation_handle sütun ve bir count sütun, aşağıdaki örnekte gösterildiği gibi:

CREATE TABLE ExpenseServiceFailedMessages (
  conversation_handle uniqueidentifier PRIMARY KEY,
  count smallint
) ;

Yordamı ClearMessageTracking sayaç için bir konuşma tablodan siler. ExpenseServiceFailedMessages, aşağıdaki örnekte gösterildiği gibi:

CREATE PROCEDURE ClearMessageTracking
  @conversationHandle uniqueidentifier
AS
BEGIN
   DELETE FROM dbo.ExpenseServiceFailedMessages
     WHERE conversation_handle = @conversationHandle ;
END ;
GO

Burada gösterilen stratejisini kasten basittir.Gereksinimlerinize uyan bir uygulama oluşturmak için temel olarak bu konuda fikirleri kullanmalısınız.Örneğin, uygulamanız durumunu korur, uygulama için Durum tablolarındaki başarısız iletileri izleme bilgilerini içerecek şekilde daha verimli olabilir.

Yukarıdaki saklı yordamlar, bir işlemin başarısız olmasına neden olabilecek hatalar işleyemez.Bu hizmet tüm işlemin başarısız olmasına neden olan bir ileti alırsa, hareket geri almak almak devam.Bu beş kez olursa otomatik zehirli ileti algılama sıra durumunu KAPALı ayarlayın.Bu durumda, farklı bir uygulamaya veya bir yönetici tarafından zehirli ileti kaldırılmalıdır.

Iletide gerçekleştirdiğiniz işlem hareket başarısız olmasına neden inanıyorsanız, hatayı işlemek için TRY ve CATCH ifadeleri kullanabilirsiniz.Hata işleme ile ilgili daha fazla bilgi için bkz: Veritabanı Altyapısı hataları işleme.