怎样让多个clientdataset更新在一个事务中 ( 积分: 50 )

L

lsz100

Unregistered / Unconfirmed
GUEST, unregistred user!
我对多个CLIENTDATASET做了修改然后保存,想在一个事务中一起保存或都不保存。这个要怎样做呀?
 
server端提供接口,调用开始/结束事务
我想只可能对数据连接进行事务操作
 
cdsEmp.RemoteServer.AppServer.BegTrans;
try
cdsEmp.ApplyUpdates(0);
//更新错误在这一句发生,但是我却永远也捕获不到,
//我想自已在异常处理里显示这里发生的错误信息该怎么办?
cdsQrObj.RemoteServer.AppServer.ComTrans;
except
on E:Exception do
begin
cdsEmp.RemoteServer.AppServer.RobTrans;
end;
 
最好安排在服务器端进行事务处理!
另外intvar:=cdsEmp.ApplyUpdates(-1);
返回错误数目
 
服务器端进行事务处理,哪客端在什么时候调用呀
cdsEmp.RemoteServer.AppServer.BegTrans;
try
cdsEmp.ApplyUpdates(0);
//更新错误在这一句发生,但是我却永远也捕获不到,
//我想自已在异常处理里显示这里发生的错误信息该怎么办?
cdsQrObj.RemoteServer.AppServer.ComTrans;
except
on E:Exception do
begin
cdsEmp.RemoteServer.AppServer.RobTrans;
end;
 
事务要放到中间层
 
在中间层写吧。或者用有事务处理的控件。
if not SQLConnection1.InTransaction then
begin
TD.TransactionID := 1;
TD.IsolationLevel := xilREADCOMMITTED;
SQLConnection1.StartTransaction(TD);
try
AS_ApplyUpdates('DataSetProvider1',Delta1,0,ErrorCount,owndata);
if ErrorCount=0 then
begin

这里继续写要提交的数据

end;

SQLConnection1.Commit(TD);
except
SQLConnection1.Rollback(TD);
Result:=ErrorCount+1;
end;
end;
 
现在我想还是把事务控制放到服务端好.但是我有这样一个问题,我在客户端修改了两个CDS,这时我想在服务端写一个方法,把这两个CDS的值在一个事务中提交.这个要怎样写,有例子吗.提交成功后怎样改变客户端的显视,不成功怎办.
百刃刀客.能不能给个完整一点的例子,我想参考学习。
 
有两种方案:
1.使用com+
try
UpdateDelta(AConStr,'TableName1',vDelta);

UpdateDelta(AConStr,'TableName2',vDelta);
SetComplete;
except
SetAbort ;
raise Exception.Create('ERROR');
end;

UpdateDelta方法的实现如下:
unit uCOM_DAO;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComServ, ComObj, VCLCom, StdVcl, bdemts, DataBkr, DBClient,
MtsRdm, Mtx, COM_DAO_TLB, Provider, DB, ADODB;
type
TCOMDAO = class(TMtsDataModule, ICOMDAO)
ADOConnection1: TADOConnection;
ADOQuery1: TADOQuery;
DataSetProvider1: TDataSetProvider;
procedure DataSetProvider1BeforeApplyUpdates(Sender: TObject;var OwnerData: OleVariant);
procedure MtsDataModuleDestroy(Sender: TObject);
private
{ Private declarations }
function GetDBConnectInfo:string;
function GetLogFilePath:string;
//当AConStr=''时 将从COM+服务器的注册表中取得数据库连接串
procedure TestConnected(const AConStr:string);
procedure WriteLogFile(const ALogStr: string );
protected
class procedure UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
override;
//当Result=rfSuccees表示查询成功;
function Open(const AConStr: WideString;
const ASqlStr: WideString;
out AData: OleVariant): integer;
safecall;
function OpenByParams(const AConStr: WideString;
const ASqlStr: WideString;
AParam: OleVariant;
out AData: OleVariant): Integer;
safecall;
//当Result=rfSuccees表示语句执行成功;
function Execute(const AConStr, ASqlStr: WideString): integer;
safecall;
//当Result=rfSuccees表示UpdateDelta执行成功;
function UpdateDelta(const AConStr, ATableName: WideString;ADelta: OleVariant): integer;
safecall;
public
{ Public declarations }
end;

implementation
uses Variants,Registry, uResultFlag;
{$R *.DFM}
class procedure TCOMDAO.UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
begin
if Register then
begin
inherited UpdateRegistry(Register, ClassID, ProgID);
EnableSocketTransport(ClassID);
EnableWebTransport(ClassID);
end else
begin
DisableSocketTransport(ClassID);
DisableWebTransport(ClassID);
inherited UpdateRegistry(Register, ClassID, ProgID);
end;
end;

function TCOMDAO.Open(const AConStr, ASqlStr: WideString;out AData: OleVariant): integer;
var
vData:OleVariant;
begin
Result :=rfCommonlyFail;
AData:=Unassigned;
try
TestConnected(AConStr);
ADOQuery1.Close;
ADOQuery1.SQL.Text:= ASqlStr ;
ADOQuery1.Open;
vData :=DataSetProvider1.Data;
if (not VarIsEmpty(vData)) and (not VarIsNull( vData )) then
begin
AData:= vData;
Result := rfSucceed;
end;
SetComplete;
except
on E: Exceptiondo
begin
WriteLogFile(#13#10+E.Message +#13#10'执行的语句为:'+ASqlStr);
SetAbort;
raise Exception.Create(FlagToHint(rfCommonlyFail));
end;
end ;
end;

function TCOMDAO.Execute(const AConStr,ASqlStr: WideString): integer;
begin
Result :=rfCommonlyFail;
try
TestConnected(AConStr);
with ADOQuery1 do
begin
Close;
SQL.Text:= ASqlStr ;
ExecSQL;
Result := rfSucceed;
end;
SetComplete;
except
on E: Exceptiondo
begin
WriteLogFile(#13#10+E.Message +#13#10'执行的语句为:'+ASqlStr);
SetAbort;
raise Exception.Create(FlagToHint(rfCommonlyFail));
end;
end ;
end;

function TCOMDAO.UpdateDelta(const AConStr, ATableName: WideString;ADelta: OleVariant): integer;
var
sSql, vErr: oleVariant ;
lErr : integer ;
sError:string;
begin
try
TestConnected(AConStr);
if not( VarIsEmpty(ADelta) or VarIsNull( ADelta ) ) then
begin
sSql := 'select * from ' + ATableName + ' where 1=2';
vErr :=DataSetProvider1.ApplyUpdates(ADelta ,0,lErr,sSql);
if (lErr > 0 ) or ( not VarIsNull(vErr)) then
begin
sError:=VarToStr( vErr );
WriteLogFile(sError +#13#10'执行的语句为:'+sSql);
raise Exception.Create(FlagToHint(rfCommonlyFail));
end;
end;
SetComplete;
except
SetAbort ;
raise Exception.Create(FlagToHint(rfCommonlyFail));
end;
end;

procedure TCOMDAO.DataSetProvider1BeforeApplyUpdates(Sender: TObject;var OwnerData: OleVariant);
var
sSQL : string ;
begin
sSQL := OwnerData ;
ADOQuery1.SQL.Text:= sSQL ;
end;

function TCOMDAO.GetDBConnectInfo: string;
var
Registry: TRegistry;
begin
Result := '';
Registry := TRegistry.Create( KEY_READ );
try
Registry.RootKey := HKEY_LOCAL_MACHINE;
Registry.OpenKey('/SOFTWARE/OSSE/Server', False);
Result := Registry.ReadString( 'DBConnectStr' );
finally
Registry.Free;
end;
end;

procedure TCOMDAO.TestConnected(const AConStr: string);
var
sCon:string;
begin
if AConStr <> '' then
begin
sCon:= AConStr;
end else
begin
sCon:=GetDBConnectInfo ;
end;

with ADOConnection1do
begin
Connected := False ;
ConnectionString := sCon;
Connected := True ;
end;

end;

procedure TCOMDAO.MtsDataModuleDestroy(Sender: TObject);
begin
if ADOConnection1.Connected then
begin
ADOConnection1.Connected := False ;
end;
end;

function TCOMDAO.OpenByParams(const AConStr, ASqlStr: WideString;
AParam: OleVariant;
out AData: OleVariant): integer;
var
i:integer;
vData:OleVariant ;
begin
Result:=rfCommonlyFail;
AData :=Unassigned;
try
TestConnected(AConStr);
with ADOQuery1 do
begin
Close;
SQL.Text:= ASqlStr ;
for i := 0 to Parameters.Count -1do
begin
Parameters.Items.Value :=AParam;
end;
Open;
vData:=DataSetProvider1.Data;
if not ( VarIsEmpty(vData) or VarIsNull( vData ) ) then
begin
AData:= vData;
Result := rfSucceed;
end;
end;
SetComplete;
except
on E: Exceptiondo
begin
WriteLogFile(#13#10+E.Message +#13#10'执行的语句为:'+ASqlStr);
SetAbort;
raise Exception.Create(FlagToHint(rfCommonlyFail));
end;
end ;
end;
{eg.
var
vSqlStr:string;
i:integer;
p:Variant;
begin
vSqlStr:='select fieldName0 from tablename where fieldname1 = :p1';
p:=VarArrayCreate([0,0], varVariant );
p[0]:='0';
with ADOQuery1 do
begin
Close;
SQL.Text:= VSqlStr ;
for i := 0 to Parameters.Count -1do
begin
Parameters.Items.Value :=p
end;
Open;
end;
end;
}
function TCOMDAO.GetLogFilePath: string;
var
Registry: TRegistry;
begin
Result := '';
Registry := TRegistry.Create( KEY_READ );
try
Registry.RootKey := HKEY_LOCAL_MACHINE;
Registry.OpenKey('/SOFTWARE/OSSE/LogPath', False);
Result := Registry.ReadString( 'Path' );
finally
Registry.Free;
end;
end;

procedure TCOMDAO.WriteLogFile(const ALogStr: string);
var
sPath,sFile : string;
tfFile : TextFile;
bSuccess : Boolean ;
begin
//得到主路径
sPath :=GetLogFilePath ;
if not DirectoryExists( sPath ) then
begin
bSuccess := CreateDir( sPath );
Assert( bSuccess );
end ;
sFile := sPath + '/' + 'LogFile.txt';
try
AssignFile( tfFile, sFile );
if FileExists( sFile ) then
begin
Append( tfFile );
end else
begin
ReWrite( tfFile, sFile );
end ;
WriteLn( tfFile, DateTimeToStr(Now) + ': '+ ALogStr );
Flush( tfFile );
finally
CloseFile(tfFile);
end;
end;

initialization
TComponentFactory.Create(ComServer, TCOMDAO, Class_COMDAO, ciMultiInstance, tmApartment);
end.
 
顶部