Aracılığıyla paylaş


Poison iletileri işleme

Bu konuda bir Hizmet Aracısı kullanan bir uygulama zehirli ileti algılamak ve zehirli ileti otomatik algılamayı dayanmayan sıradan ileti kaldırma yolu açıklanmaktadır.

Hizmet Aracısı zehirli ileti otomatik algılama sağlar.zehirli ileti otomatik algılama, beş kez sıradan iletileri alır bir hareketi geri alır, sıra durumu off olarak ayarlar.Bu özellik, bir uygulama olamaz çok zararlı hata karşı koruma sağlar algılamak program aracılığıyla.Ancak, bir uygulama için normal bir işlem bu özelliğin güvenmemelisiniz.zehirli ileti otomatik algılama sırası durdurması nedeniyle, zehirli ileti kaldırılıncaya kadar bu özellik etkin bir şekilde uygulama için tüm işlemleri durdurur.Bunun yerine, bir uygulama deneyeceği, algılamak ve uygulama mantığı bir parçası olarak zarar iletileri Kaldır.

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

  • Hata sayısı, uygulamanız için güvenilir mi?Uygulamanıza bağlı olarak, saat saat başarısız ileti almak için normal olabilir.Örneğin, bir sipariş girişi uygulaması yeni bir müşteri kaydı ekler hizmet'den daha az işlem saat sipariş işleme hizmet alabilir.Bu durum, yeni bir müşteri için sipariş hemen işlenemez normal olabilir.Uygulama bir ileti zehirli ileti olup olmadığını karar verirken gecikmesi için hesap gerekir.hizmet Çeşitli hatalar ileti kaldırılmadan önce izin vermeniz gerekebilir.

  • Uygulamanızı hızla ve güvenle asla başarabilir algılamak için bir iletinin içeriği kontrol edebilirsiniz?Bu durumda, program iletiyi işleyemedi sayısı sayım'den daha iyi bir strateji budur.Örneğin, bir çalışan adı veya bir çalışanın kimlik numarasını içeren bir gider raporu işlenemez.Bu durum, program hemen bildiren bir hata ile işlenen yerine, iletiyi işlemek için çalışırken bir iletisi verirse daha verimli olabilir.Diğer doğrulama düşünün.Kimlik numarası var, ancak atanan sayıları (örneğin, negatif bir sayı) aralık dışında kalan, örneğin, uygulamayı konuşmaya hemen sona erdirebilir.

  • Bir iletiyi herhangi bir hatadan sonra kaldırmanız gerekir?Her iletinin sınırlı bir ömrü olduğu uygulama iletileri yüksek hacimli işler, işlemin başarısız olmasına neden olan herhangi bir iletiyi hemen kaldırmak için en etkili olabilir.Örneğin, ileti hedef hizmet ilerleme raporu sağlıyorsa, boş ilerleme raporu alma iletisi işlemeden tarafından yapılıyor atmak başlatma hizmeti seçebilirsiniz.Bu durum, konuşmaya devam eder.

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

  • Uygulama hatası ve iletinin içeriği oturum açması gerekir?Çoğu durumda, bu gerekli değildir.Ancak, bazı uygulamalar için iletinin içeriğini koruma uygun olabilir.

  • Uygulama hatası hakkında diğer bilgileri oturum açması gerekir?Bazı durumlarda, görüşme hakkında diğer bilgileri izlemek isteyebilirsiniz.Örneğin, Katalog görünümü kullanabilirsiniz sys.conversation_endpoints zehirli ileti oluşturulan uzak broker örnek tanımlamak için.

  • Ne sizin uygulama son hata ile konuşma veya gereken anlaşma konuşma kapatmadan bir hatayı göstermek bir uygulama hizmet için izin mi?Alma, birçok hizmetler için bir zehirli ileti sözleşmede açıklanan görevi tamamlanmış olduğunu anlamına gelir.Bu durum, uygulama bir hata ile yapılan görüşme sona erer.Diğer durumlarda, konuşma bir ileti başarısız olsa bile devam etmek mümkün olabilir.Örneğin, bir ambar kat stok veri alan bir hizmet bazen bir bilinmeyen parça numarasını içeren bir ileti alabilirsiniz.Konuşma bitiş yerine hizmet iletiyi bir sonraki incelemek için işleç için ayrı bir tablo kaydetmek saat.

Örnek: Poison Message algılama

Bu Transact-SQL örnek bir basit, durum bilgisi olmayan hizmet işleme mantığı içerir gösterir. zararlı ileti Saklı yordam bir ileti alır önce yordamı hareket kaydeder.Yordam, bir iletiyi işleyemediğinde, hareket kaydetme için yedekleme yordamı alır üzerine gelin.Sıraya ileti tutacak devam ederken kısmi geri alma verir bir kilit konuşma grubundaki ileti.Tutmak programın devam etmesi nedeniyle konuşma grubu kilit, programın başarısız iletileri ileti başka bir sıra okuyucu işlerler riski olmadan bir listesini tutan bir tablo güncelleştirebilirsiniz.

Aşağıdaki örnek etkinleştirmesi tanımlanmakta 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 AdventureWorks2008R2.dbo.AddExpenseReport
              @report = @expenseReport ;
            IF @@ERROR <> 0
             BEGIN
               ROLLBACK TRANSACTION UndoReceive ;
               EXEC TrackMessage @conversationHandle ;
             END ;
            ELSE
             BEGIN
               EXEC AdventureWorks2008R2.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 bir ileti başarısız olma sayısı izler.Ne zaman ileti yok oldu yordamı için iletinin içine yeni bir sayaç ekler önce tablo ExpenseServiceFailedMessages.Aksi takdirde yordam sayaç sayısı iletisi başarısız için denetler.Sayaç önceden tanımlanmış bir sayıdan azsa yordamı sayacı artırır.Sayaç önceden tanımlanmış sayıdan büyük olduğunda, yordamı bir hata ile konuşma bitiş ve görüşme 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ını ExpenseServiceFailedMessages basitçe içeren bir conversation_handle sütun ve bir count Aşağıdaki örnekte gösterildiği gibi sütun:

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

Yordam ClearMessageTracking bir konuşma için sayaç siler tablo 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 kasıtlı basit stratejisidir.Gereksinimlerinize uyan bir uygulama oluşturmak için temel olarak bu konudaki fikirleri kullanmalısınız.Örneğin, uygulamanızın durumunu korur, uygulamanın durumu tablolarına başarısız iletileri izleme bilgilerini eklemek için daha verimli olabilir.

Bir işlemin başarısız olmasına neden olabilecek hatalar yukarıdaki saklı yordamları işleyemez.Bu, hizmet tüm işlemin başarısız olmasına neden olan bir ileti alır hareket geri döner.Bu beş kez olursa, zehirli ileti otomatik algılama olur küme off için sıra durumu.Bu durum, zehirli ileti farklı bir uygulamaya veya bir yönetici tarafından kaldırıldı.

İletide gerçekleştirdiğiniz işlem işlem başarısız olmasına neden düşünüyorsanız, hatayı işlemek için try ve catch deyimi kullanabilirsiniz.Hataları işleme hakkında daha fazla bilgi için bkz: Veritabanı Altyapısı hataları işleme.