Hi Avanish,
The point of web services is to run at a different level of abstraction from
internal-to-the-enterprise database actions. If the database activities in
question cannot be coordinated through normal COM and DTC operations
(without web services), then you may want to look at using a more
traditional submit-and-acknowledge method. So, my first suggestion is that
you look at whether you can coordinate through DTC and COM+.
Note: if you cannot use DTC and COM+, your second option is MSMQ. Your
service on A can send transactions to B and C, where components can
participate in the transaction. This is reliable and distributed. It is
also not commonly used.
The third option is to use web services. If you cannot use the other two,
then read on...
This method requires that you have, for at least one of your two databases,
the ability to MANUALLY roll back the data change.
(You will quickly see why, for many developers, this is not what you'd
expect. However, this is precisely how thousands of B-to-B systems handle
synchronization of a data record across distance and time... This is the
level of abstraction that web services operate best at.)
So, let's say that in the system under service B, you are doing an insert,
while in the system under C, you are doing an update.
In this case, your order of interaction is:
A calls B (submit - insert)
B acknowledges success
A calls C (submit - update)
C acknowledges success
A calls B (commit)
B acknowledges commit
Note that A calls B twice, but only calls C once. This is because it is
more difficult to roll back an update than it is to roll back an insert.
Also, it would be best if the entire data structure that A will "submit", to
either B or C, is the same for both. Let this be a "business document"
instead of a database transaction. (If this is not a typical concept for
you, check out
http://weblogs.asp.net/nickmalik/arc...21/246020.aspx which
discusses how I used SOA to solve a db replication issue using business
documents). On the other hand, the last call, from A to B to commit the
transaction, is a message that references the transaction... it does not
need to be a business document.
The key to this method, with using manual rollback, is that service B has to
either have enough state information to roll back a prior transaction or
must have returned enough data for the controller (service A) to request it.
My preference is the first option: B knows how it commits data, it should
know how to roll it back.
So, a failure scenario would look like this:
A calls B (submit - insert)
B acknowledges success
A calls C (submit - update)
C acknowledges failure or fails to respond
A calls B (rollback)
B acknowledges rollback
For web service B to be able to roll back a transaction, it needs to give
the transaction itself a unique id and store that id in a table along with
enough information for it to know how to roll back the associated records
(perhaps by recording the primary keys of the inserted records, or by
storing actual SQL strings needed to undo or compensate for the change.).
The second call, from A to B (commit) actually just cleans up this record or
marks it as "confirmed". It is a totally unnecessary call if you decide to
clean up the record yourself after some time. On the other hand, this kind
of information may prove useful for auditing, so it's up to you if you
decide to clean it up at all!
So the calls to submit are actually normal database calls. There may very
well be a transaction in each one, to get their own internal manipulations
to be consistent.
The call to confirm (A to B) simply marks the transaction as "confirmed".
So, you solve the interaction problem, but you are left with another: how do
do a set of database operations that can be rolled back?
method 1) compensation
method 2) manual rollback
method 3) Staging table mechanism
Compensation means that you cannot actually "undo" the transaction. You can
reverse the effects, but both the initial transaction, and the compensating
transaction, are normal and auditably transactions in the destination
system. This is very typical for accounting systems. For example, a vendor
receives a purchase order (the submit) and then, some time later, the order
is cancelled (the rollback). The records in the database were not actually
removed. Both transactions show up on reports. However, the accounting
system remains consistent.
Manual Rollback is the most dangerous and error-prone method of the three.
This method means that you actually store enough information to "undo" the
original transaction. In other words, if you inserted records in the
initial transaction, this method would have you delete them now. If the
transaction itself is complex, this gets hard, fast. However, you have to
ask yourself if decisions or actions may have occurred in system B as a
result of the existence of the record, and then you remove the record...
what about the decisions? Can two different financial reports, produced
minutes apart, produce different numbers with no way to reconcile them?
Staging Table Mechanism - this means that the initial transaction from A to
B is not written to the actual target tables. Instead, it is written to a
"staging table" on the target database. All checks will be done to make
sure that the record is likely to be acceptable to the target database
before adding it to the staging tables. Once again, a unique transaction id
is passed back to A. This transaction id actually refers to the full set of
records that need to be written to the target database. Now, the service B
waits for caller A to send a "commit" message referencing the transaction
id. When it does, it then commits the data from the staging table to the
production table. This is less likely to fail because most of the database
checks have already occurred on system B.
So three different methods to work within this overall mechanism.
All this is a very good reason why we don't like to roll our own.
--- Nick
"Avanish Pandey" <av******@hotmail.com> wrote in message
news:uz**************@TK2MSFTNGP12.phx.gbl...
Hello All
We have 3 differen services (in 3 different server) Service A,B,C . We
want to implement distributed transaction when call methods of B and C
from A. Is it possible? if yes then how?
I have read the doc regarding this:
http://www.developer.com/net/asp/article.php/3385631
but it will not work when methods are in different services on
different server.
Thanks in Advance
*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!