Now that we have changed the service to support distributed transaction and let the client propagate the transaction to the service, we will test this. We will first change the Distributed Transaction Coordinator and Firewall settings for the distributed transaction support of the WCF service, then propagate a transaction from the client to the service, and test the multiple database support of the WCF service.
In a subsequent section, we will call two services to update two databases on two different computers. As these two updates are wrapped within one distributed transaction, Microsoft Distributed Transaction Coordinator (MSDTC) will be activated to manage this distributed transaction. If MSDTC is not started or not configured properly, the distributed transaction will not be successful. In this section, we will learn how to configure MSDTC on both machines.
You can follow these steps to configure MSDTC on your local and remote machines:
dcomcnfg.exe
).Remember you have to make these changes for both your local and remote machines.
Even though Distributed Transaction Coordinator has been enabled, the distributed transaction may still fail if the firewall is turned on and hasn't been set up properly for MSDTC.
To set up the firewall for MSTC, follow these steps:
windowssystem32msdtc.exe
), if it is not already on the list. Make sure the checkbox before this item is checked.Now the firewall will allow msdtc.exe
to go through so our next test won't fail due to the firewall
restrictions.
Now we have the services and MSDTC ready. In this section, we will rerun the distributed test client and verify the distributed transaction support of the enhanced WCF service.
First we will test the
distributed transaction support of the WCF service within one database. We will try to update two products (30
and 31
). The first update will succeed but the second update will fail. Both updates are wrapped in one client transaction, which will be propagated into the service, and the service will participate in this distributed transaction. Due to the failure of the second update, the client application will roll back this distributed transaction at the end and the service should also roll back every update that is within this distributed transaction. So, in the end, the first update should not be committed to the database.
Now follow these steps to do this test:
30
and 31
as product IDs in the top two textboxes.30.89
and -14.5
as new prices in the New Price textboxes.From the output window, we can see that the prices of both products remain unchanged which proves that the first update has been rolled back. From this output, we know that both service calls are within a distributed transaction and the WCF service now fully supports the distributed transaction within one database.
Next we will test the distributed transaction support of the WCF service with two databases or machines involved. As mentioned before, this is a true distributed transaction test as MSDTC will be activated only when the machine boundary is crossed.
In this test, we will try to update two products (product 30
and 31
). However, this time the second product (product 31
) is in a remote database on another machine. As in the previous test, the first update will succeed, but the second update will fail. Both updates are wrapped in one client transaction, which will be propagated into the service and the service will participate in this distributed transaction. Due to the failure of the second update, the client application will roll back this distributed transaction at the end and the service should also roll back every update that is within this distributed transaction. The first update should finally not be committed to the database.
Now follow these steps to carry out this test:
30
and 31
as product IDs in the top two textboxes.30.89
and -14.5
as new prices in the New Price textboxes.From the output window we can see that the prices of both products remain unchanged, which proves that the first update has been rolled back. From this output, we know that both service calls are within a distributed transaction and the WCF service now fully supports the distributed transaction with multiple databases involved.
Now to prove that the
distributed transaction support works, click on the Get Product Details button to refresh product1
(make sure Get and Update 2nd Product in Remote Database is still checked), enter two valid prices, such as 30.89
and 14.5
, then click on the Update Price button. This time you should see that both products' prices are updated successfully.
To see the status of all your distributed transactions, you can go to Component Services, and select Transaction Statistics, as shown in the following screenshot:
For the last successful test, you might not get an output as shown in the preceding screenshot, but instead still get an exception. If you debug your code, inside the UpdatePrice
operation of your product service (note you need to step in to your service code from the client UpdateRemotePrice
method), when you examine the update product exception, you may see one of the following error messages:
This might be because you have not set your Distributed Transaction Coordinator or firewall correctly. In this case, you need to follow the instructions in the previous sections to configure these settings, then come back and redo these tests.
If you get an exception of the OptimisticConcurrencyException
type inside the UpdateRemotePrice
method, double-check your client proxy object within the UpdateRemotePrice
method. You may have forgotten to change the client proxy from ProductServiceProxy.ProductServiceClient
to RemoteProductServiceProxy.ProductServiceClient
. Once you have corrected it, you should be able to perform this test successfully.
If you get a timeout
exception while you are debugging, increase your client application's service binding settings of sendTimeout
and receiveTimeout
to a larger value such as 5 minutes and try again.