2017-07-28 84 views
1

客戶端應用程序在一個TransactionScope中調用WCF服務,希望在呼叫失敗時回滾整個事務。應用程序&服務工作正常,但如果兩個客戶端同時向WCF服務發送請求,其中一個客戶端會發生死鎖錯誤。不同線程中的WCF事務

這是在客戶端應用程序的代碼:

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> 

我在做什麼錯誤?

回答

1

我找到了正確的配置。

  • ServiceBehavior屬性的ConcurrenyMode屬性必須被指定以下ConcurrencyMode.Multiple值:服務合同必須按如下方式構造。
  • OperationBehavior屬性的TransactionAutoComplete屬性必須爲所有操作。事務不能跨越多個操作。
  • ServiceBehavior屬性的該服務的ReleaseServiceInstanceOnTransactionComplete屬性必須設置爲。您必須通過關閉客戶端連接來顯式釋放服務實例。
  • ServiceBehavior屬性爲服務的TransactionAutoCompleteOnSessionClose屬性必須真實。當會話結束時,所有線程中的所有事務都必須終止。因爲SQL操作之前

    <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 
    
0

我的猜測是,是因爲你所提交的事務之前但從邏輯上看關閉客戶端,至少它應該是這樣的:

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 
+0

我建立到服務的連接之前還打開事務執行。我希望在一次交易中擁有一切。 – battleboimatze

+0

服務合同配置如下:TransactionAutoComplete:= True – battleboimatze

+0

該服務也可以很好地工作。返回作品。只有當兩個客戶同時訪問服務時纔有問題。 – battleboimatze