You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨事务WCF调用服务器及跨服务器Web服务交互实现咨询

Alright, let's walk through how to implement this cross-server WCF interaction properly, especially considering the database lock dependency you mentioned. Here's a step-by-step breakdown tailored to your scenario:

1. Expose deliveryRetrieved.svc on Server2 for Server1 to Call

First, you need to set up the WCF service on Server2's Windows Service that listens for the "delivery retrieved" notification.

Define the Service Contract & Implementation

Create a service contract that Server1 will invoke, and implement the logic to release the database lock for the delivery ID:

[ServiceContract]
public interface IDeliveryNotificationService
{
    [OperationContract]
    void DeliveryRetrieved(int deliveryId);
}

public class DeliveryNotificationService : IDeliveryNotificationService
{
    public void DeliveryRetrieved(int deliveryId)
    {
        // Logic to unlock the delivery ID in Server2's database
        using (var dbContext = new Server2DbContext())
        {
            var delivery = dbContext.Deliveries.FirstOrDefault(d => d.Id == deliveryId);
            if (delivery != null)
            {
                delivery.IsLocked = false; // Or release a pessimistic lock here
                dbContext.SaveChanges();
            }
        }
    }
}

Configure WCF Endpoints

Set up a WCF endpoint in Server2's Windows Service configuration (either via app.config or code) so Server1 can reach it. Choose a binding that fits your network environment—netTcpBinding for fast internal network communication, or basicHttpBinding if you need broader compatibility:

<system.serviceModel>
  <services>
    <service name="Server2.DeliveryNotificationService">
      <endpoint 
          address="net.tcp://localhost:8080/DeliveryNotificationService"
          binding="netTcpBinding"
          contract="Server2.IDeliveryNotificationService" />
    </service>
  </services>
</system.serviceModel>
2. Add WCF Client in Server1's Web Service to Call Server2

Next, set up Server1's processingComplete.svc to invoke Server2's deliveryRetrieved.svc once it finishes processing the delivery ID.

Generate WCF Client Proxy

In Server1's Web Application project, add a Service Reference pointing to Server2's WCF endpoint (e.g., net.tcp://server2-machine:8080/DeliveryNotificationService). This will auto-generate a client proxy class.

Invoke the Notification Service in processingComplete.svc

Update your processingComplete.svc implementation to call Server2's service after handling its own business logic:

public class ProcessingCompleteService : IProcessingCompleteService
{
    public void ProcessingComplete(int deliveryId)
    {
        // Step 1: Execute your core business logic for the delivery ID
        HandleDeliveryProcessing(deliveryId);

        // Step 2: Notify Server2 that the delivery ID has been retrieved
        try
        {
            using (var notificationClient = new DeliveryNotificationServiceClient())
            {
                notificationClient.DeliveryRetrieved(deliveryId);
                notificationClient.Close();
            }
        }
        catch (Exception ex)
        {
            // Critical: Handle call failures (network issues, Server2 downtime)
            // Log the error and implement retry logic to avoid stale locks
            Logger.Error($"Failed to notify Server2 for delivery {deliveryId}: {ex.Message}");
            // Add to a retry queue (e.g., SQL table, Hangfire) for later processing
            EnqueueRetryNotification(deliveryId);
        }
    }

    private void HandleDeliveryProcessing(int deliveryId)
    {
        // Your Server1 business logic here
    }

    private void EnqueueRetryNotification(int deliveryId)
    {
        // Logic to store failed notifications for retry
    }
}
3. Handle Cross-Transaction Requirements (If Needed)

If you need the processing on Server1 and the lock release on Server2 to be atomic (i.e., either both succeed or both fail), you'll need to use distributed transactions:

Enable Transaction Flow in WCF

Update both Server2's service contract and binding to allow transaction flow:

[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
void DeliveryRetrieved(int deliveryId);
<bindings>
  <netTcpBinding>
    <binding name="TransactionalTcpBinding" transactionFlow="true" />
  </netTcpBinding>
</bindings>

Wrap Calls in a Transaction Scope on Server1

Use TransactionScope to wrap both Server1's processing and the WCF call in a distributed transaction:

using (var transactionScope = new TransactionScope(TransactionScopeOption.Required))
{
    HandleDeliveryProcessing(deliveryId);
    using (var notificationClient = new DeliveryNotificationServiceClient())
    {
        notificationClient.DeliveryRetrieved(deliveryId);
        notificationClient.Close();
    }
    transactionScope.Complete();
}

Note: Distributed transactions require the MSDTC (Microsoft Distributed Transaction Coordinator) service to be configured and running on both Server1 and Server2.

4. Critical Reliability Considerations

Cross-server calls are prone to failures, so don't skip these:

  • Retry Logic: Implement exponential backoff for failed calls to avoid overwhelming Server2
  • Dead-Letter Queue: For notifications that keep failing, store them in a persistent queue and process them periodically
  • Logging: Track every notification attempt (success/failure) for debugging
  • Lock Timeouts: On Server2, set a timeout on the database lock so it doesn't stay locked indefinitely if the notification never arrives
5. Database Lock Best Practices

Instead of using long-lived pessimistic locks on Server2's database, consider:

  • Optimistic Locking: Use a Version column or IsLocked flag to track lock state, which avoids holding database locks for extended periods
  • Short Locks: If you must use pessimistic locks, keep them as brief as possible and release them immediately when the notification is received

内容的提问来源于stack exchange,提问作者Abhishek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 02:23:43