提问者:小点点

不同线程中的WCF事务


客户端应用程序正在一个TransactionScope中调用WCF-Service,希望在调用失败时回滚整个事务。应用程序

这是客户端应用程序中的代码:

 Using transcop As New TransactionScope(TransactionScopeOption.Required, New TransactionOptions() With {.IsolationLevel = IsolationLevel.Serializable})
        Try
            Dim test = LeaProS.RechnungenService.RechnungenInternalWSClient.FacadePdfVerarbeitungInternalWS.PdfVerarbeitungLoslegen(11928, True)

            transcop.Complete()

        Catch ex As Exception
            transcop.Dispose()
            Throw
        End Try
    End Using

Public Shared Function PdfVerarbeitungLoslegen(idAusGeplanteRechnungen As Integer, lettershopDrucken As Boolean) As Byte()

    Dim client As RechnungInternalWSClient = Nothing

    Try
        ' Verbindung zum Webservice initialiseren.
        client = New RechnungInternalWSClient("NetTcpBinding_IRechnungInternalWS")
        client.Open()

        ' verarbeitung starten
        Dim retval = client.PdfVerarbeitungLoslegen(idAusGeplanteRechnungen:=idAusGeplanteRechnungen, LettershopDrucken:=lettershopDrucken)
        client.Close()
        client = Nothing

        'PDF zurückgeben.
        Return retval.pdf

    Catch ex As Exception
        RechnungenUtils.ClientKontrolliertBeenden(client)
        Throw
    End Try

End Function

这是服务合同:

<ServiceBehavior(ConcurrencyMode:=ConcurrencyMode.Multiple,
InstanceContextMode:=InstanceContextMode.PerCall,
UseSynchronizationContext:=True,
TransactionIsolationLevel:=System.Transactions.IsolationLevel.Serializable,
TransactionTimeout:="00:00:30",
ReleaseServiceInstanceOnTransactionComplete:=False
)>
Public Class RechnungInternalWS
Implements IRechnungInternalWS

<OperationBehavior(TransactionScopeRequired:=True, 
TransactionAutoComplete:=True)>
Public Function PdfVerarbeitungLoslegen(idAusGeplanteRechnungen As Integer, 
LettershopDrucken As Boolean) As RechnungPDFOriginal Implements 
IRechnungInternalWS.PdfVerarbeitungLoslegen
' do something
End Function

这些是配置文件:

<endpoint address="net.tcp://eldienste:555/IRechnungInternalWS"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IRechnungInternalWS"
contract="ServiceReference.IRechnungInternalWS" name="NetTcpBinding_IRechnungInternalWS" />

<binding name="NetTcpBinding_IRechnungInternalWS" closeTimeout="00:01:00"
      openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00"
      transactionFlow="True" transferMode="Buffered" transactionProtocol="OleTransactions"
      hostNameComparisonMode="StrongWildcard" listenBacklog="250"
      maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="250"
      maxReceivedMessageSize="65536">
  <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2147483646"
      maxBytesPerRead="4096" maxNameTableCharCount="16384" />
  <reliableSession ordered="true" inactivityTimeout="00:10:00"
      enabled="false" />
  <security mode="None">
    <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
    <message clientCredentialType="Windows" />
  </security>
</binding>

我做错了什么?


共2个答案

匿名用户

我找到了正确的配置。服务合同必须配置如下:

>

  • 服务行为属性的ConcyyMode属性必须分配以下ConcycyMode.多值。
  • 操作行为属性的TransactionAuto完成属性对于所有操作都必须为true。事务不能跨越多个操作。
  • 服务的ServiceBe行为属性的ReleaseServiceInstanceOnTransaction完全属性必须设置为false。您必须通过关闭来自客户端的连接来显式释放服务实例。
  • 服务的ServiceBe行为属性的TransactionAutoCompleteOnSessionClose属性必须为true。所有线程中的所有事务都必须在会话结束时终止。

    <ServiceBehavior(ConcurrencyMode:=ConcurrencyMode.Multiple,
    InstanceContextMode:=InstanceContextMode.PerSession,
    UseSynchronizationContext:=False,TransactionIsolationLevel:=System.Transactions.IsolationLevel.Serializable,
    TransactionTimeout:="00:00:30",
    ReleaseServiceInstanceOnTransactionComplete:=False,
    TransactionAutoCompleteOnSessionClose:=True
    )>
    Public Class RechnungInternalWS
    Implements IRechnungInternalWS
    
    
    <OperationBehavior(TransactionScopeRequired:=True, 
    TransactionAutoComplete:=True)>
    Public Function PdfVerarbeitungLoslegen(idAusGeplanteRechnungen As 
    Integer, LettershopDrucken As Boolean) As RechnungPDFOriginal Implements 
    IRechnungInternalWS.PdfVerarbeitungLoslegen
    
    ' do something
    End Function
    
    End Class
    

  • 匿名用户

    我的猜测是,这是因为您在提交事务之前关闭了客户端,至少从逻辑角度来看,它应该如下所示:

    Public Shared Function PdfVerarbeitungLoslegen(idAusGeplanteRechnungen As Integer, lettershopDrucken As Boolean) As Byte()
    
        Try
            Using transcop As New TransactionScope(TransactionScopeOption.Required, New TransactionOptions() With {.IsolationLevel = IsolationLevel.Serializable})
                Using client = New RechnungInternalWSClient("NetTcpBinding_IRechnungInternalWS")
                    client.Open()
                    Dim retval = client.PdfVerarbeitungLoslegen(idAusGeplanteRechnungen:=idAusGeplanteRechnungen, LettershopDrucken:=lettershopDrucken)
                    transcop.Complete()                  
                    Return retval
                End Using
            End Using
        Catch ex As Exception
            RechnungenUtils.ClientKontrolliertBeenden(client)
            Throw
        End Try
    
    End Function