Использование Microsoft Transaction Server
Для тестирования распределенных транзакций запустим приложение. Введем адрес в компонент TEdit, выберем строку в списке товаров и нажмем на кнопку "Заказать" (рис. 26). Рис. 26. Тестирование распределенной транзакции В результате получим сообщение о том, что заказ принят Нажав на кнопку Connect, обновим данные в компонентах TDBGrid. При этом запись, выбранная ранее, исчезнет, а в двух других компонентах TDBGrid появятся две новых (рис. 27): Рис. 27. Результат выполнения распределенной транзакции Отметим, что, если не нажать на кнопку Connect, данные в компонентах TDBGrid останутся прежними (в данном примере не предусмотрено обновление данных после выполнения транзакции), у пользователя есть возможность попытаться повторно выбрать для заказа уже выбранную ранее запись (то есть заказать товар, заказ на который уже оформлен). В этом случае один из трех серверных объектов будет пытаться удалить уже удаленную запись (если вспомнить текст соответствующего SQL-запроса, она идентифицируется значением первичного ключа), и в этом случае соответствующая часть транзакции не завершится. Соответственно, произойдет откат назад всей распределенной транзакции. Сведения о завершенных и отмененных транзакциях можно получить, выбрав в MTS Explorer опцию Transaction Statistics (рис. 28): Рис. 28. Просмотр статистики выполнения и отката распределенных транзакций Если вспомнить, что первичные ключи в нашей таблице товаров создаются с использованием генератора, созданного нами на сервере IB Database, становится очевидным, что создаваемые в этой таблице новые записи будут иметь значения первичного ключа, не совпадающие со значениями первичных ключей уже удаленных записей. Поэтому вероятность коллизий, связанных с удалением не той записи, в данном случае равна нулю. Отметим, однако, что при создании подобного рода серверных объектов и их клиентов следует всегда пытаться исключить возможность ошибочных действий пользователя, поэтому более корректным было бы иметь следующий обработчик события, связанного с нажатием на кнопку "Заказать":
var n:integer;val:double;gnam,addr:widestring;
begin
try
n:= ClientDataSet1.FieldByName('GOODSNUMBER').Value;
val:= ClientDataSet1.FieldByName('PRICE').Value;
gnam:= ClientDataSet1.FieldByName('GOODSNAME').Value;
addr:=Edit1.Text;
DcomConnection2.Connected:=true;
DCOMConnection2.AppServer.DoTrans(n,val,addr,gnam);
ShowMessage('Заказ принят');
Button2Click(self);
except
ShowMessage('Заказ не принят ');
end;
DcomConnection2.Connected:=false;
end;
begin
try
DCOMCOnnection1.Connected:=true;
DCOMCOnnection2.Connected:=true;
DCOMCOnnection3.Connected:=true;
CLientdataset1.data:=Dcomconnection1.Appserver.GetGoods;
CLientdataset2.data:=Dcomconnection2.Appserver.GetPays;
CLientdataset3.data:=Dcomconnection3.Appserver.GetDelivery;
Button1.Enabled:=true;
except
Button1.Enabled:=false;
ShowMessage('Один из серверных объектов недоступен');
end;
DCOMCOnnection1.Connected:=false;
DCOMCOnnection2.Connected:=false;
DCOMCOnnection3.Connected:=false;
end;
Отправить комментарий