Why shouldn't I control transactions from the client?
Several reasons, actually:
- It's not stateless. If you do something like this:
DCOMConnection1.AppServer.BeginTransaction;
try
CDS1.ApplyUpdates(0);
CDS2.ApplyUpdates(0);
DCOMConnection1.AppServer.CommitTransaction;
except
DCOMConnection1.AppServer.RollbackTransaction;
end;
You have no way to control which server each call will go to.
- Using the same code above as an example, if CDS1 goes OK with no errors, but
an error occurs during CDS2, you will be in an inconsistent state with CDS1 the next
time you want to commit your changes.
- Your client should know absolutely nothing about the transactions on
the server. If you need to change the semantics of the transaction,
then you need to re-deploy the client to your entire userbase. Not
good. (Data-Access tier vs. GUI tier)
- Failed connections might mean rolling a
transaction back unnecessarily. For example, you start the tran, do
some changes and the client crashes. If you would have just specified
everything up front, the tran would commit because the work would
already be on the server. Now, it's left hanging and the DBMS will
eventually timeout and do a rollback.
- Increased network traffic. The goal of multi-tier is to reduce
round-trip calls. Putting control of server transactions on the client
hardly qualifies, since it would have to go round-trip at LEAST 3
times.
- A transaction should be quick. You might be able to achieve this one
on the client, but the temptation is also there to ignore this, and
start your transaction inside an edit. Impossible to do if you bundle
it up and send it to the server.