--关于在COM+中使用ADO连接Access 2000的问题!--(100分)

  • 主题发起人 主题发起人 华健
  • 开始时间 开始时间

华健

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大哥!
小弟近日做一个项目时,碰到一个非常奇怪的问题,表述如下:
我用Access 2000建立一个数据库,库中有一个表为Logs,用于记录用户登录的信息。
其中有字段ID(自动编号),LogTime(日期/时间)...几个字段。
我想建立一个COM+对象,用于记录所有用户对系统的操作。
建立一个“需要新事务”的COM+数据模块,放置ADOConnection及ADODataSet以连接到
Access 2000数据库。
建立一个方法WriteLog来将信息写入数据库。此方法接受几个WideString类型的参数。
try
...
ADODataSet1.Active:=true;
ADODataSet1.Insert;
ADODataSet1.FieldByName('LogTime').Value:=第一个参数;
...
ADODataSet1.Post
SetComplete;
except
SetAbort;
end;
这样应该没有问题。但不管传入什么数据,事务总是被取消。
如果我用ADOConnection连接MS Sql Server 7中相同结构的表,则上述方法能够正确完成!
我用一个只接受一个Variant参数vResult的方法来进行测试:
try
ADODataSet1.Active:=true;
SetComplete;
vResult:='Complete';
except
SetAbort;
vResult:='Abort';
end;
在客户端调用返回为'Abort';但在设计时可设ADODataSet的Active为True.
我百思不得其解!

哪位大哥帮帮忙?告诉小弟是为什么?
ps:D6(up 1) + MDAC2.6 + jet4SP5
 
有三层应用的高手吗?
帮帮小弟吧!
Help me!
 
我不知到是什么原因,但我用的一般是用sql语句commandtext,然后在设定active为true。
你可以试试可不可以,关注...
 
我试过了,没用。
 
我自己试了一下是可以的,下面是我的源代码,我把数据库组件放到一个DataModule里了,
又将AdoDataSet的CommandType设为cmdTable,CommandText为test表,active为true。可以调用
并插入记录。(D6,Access 2000)
unit Unit1;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
ActiveX, Mtsobj, Mtx, ComObj, Project1_TLB, SysUtils, Unit2, StdVcl;
type
TAccessTest = class(TMtsAutoObject, IAccessTest)
private
FDataModule: TDataModule2;
protected
procedure WriteLogin(const UserName: WideString);
safecall;
{ Protected declarations }
public
procedure Initialize;
override;
destructor Destroy;
override;
end;

implementation
uses ComServ, forms;
destructor TAccessTest.Destroy;
begin

inherited;
FDataModule.Free;
end;

procedure TAccessTest.Initialize;
begin
inherited;
FDataModule := TDataModule2.Create(forms.Application);
end;

procedure TAccessTest.WriteLogin(const UserName: WideString);
begin
try
try
FDataModule.ADODataSet1.Active:=true;
FDataModule.ADODataSet1.Insert;
FDataModule.ADODataSet1.FieldByName('UserName').AsString:=UserName;
FDataModule.ADODataSet1.FieldByName('LoginTime').AsDateTime:=Now;
FDataModule.ADODataSet1.Post;
// statements to try
except
SetAbort;
end;
// try/except
SetComplete;
finally // wrap up
FDataModule.ADODataSet1.Active := false;
end;
// try/finally
end;
initialization
TAutoObjectFactory.Create(ComServer, TAccessTest, Class_AccessTest,
ciMultiInstance, tmApartment);
end.
下面是插入记录的代码
procedure TForm1.Button1Click(Sender: TObject);
var
vMTS:IAccessTest;
begin
try
vMTS := CoAccessTest.Create;
vMTS.WriteLogin(Edit1.Text);
vMTS := nil;
Edit2.Text:='ok';
except
Edit2.Text:='erroe';
// free resources
end;
// try/finally
end;
 
to flintsoft:
您采用的方法是使用COM+对象结合DataModule来处理数据库数据。
我是直接使用MTS数据模块来连接ACCESS 2000的。
这两者有一些差别(如事务等),可能您的方法可行(如果可行我将付分),但如果可行的话,
为什么使用MTS数据模块就不行了呢?
我猜想是ACCESS 2000不支持“新事务”的关系。但写日志必须要保证不被其它对象的事务
链所干扰。不知您有什么看法?
谢谢!
 
我也用MTS数据模块试了试,也没有问题啊。下面是代码,你看看和你的有什么区别啊?
unit Unit1;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComServ, ComObj, VCLCom, StdVcl, bdemts, DataBkr, DBClient,
MtsRdm, Mtx, Project1_TLB, DB, ADODB;
type
TTestAccess = class(TMtsDataModule, ITestAccess)
ADOConnection1: TADOConnection;
ADODataSet1: TADODataSet;
private
{ Private declarations }
protected
class procedure UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
override;
procedure WriteLog(const UserName: WideString);
safecall;
public
{ Public declarations }
end;
var
TestAccess: TTestAccess;
implementation
{$R *.DFM}
class procedure TTestAccess.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;

procedure TTestAccess.WriteLog(const UserName: WideString);
begin
try
ADODataSet1.Active:=true;
ADODataSet1.Insert;
ADODataSet1.FieldByName('Username').Value:=UserName;
ADODataSet1.FieldByName('LoginTime').Value:=Now;
ADODataSet1.Post;
SetComplete;
except
SetAbort;
end;
end;
initialization
TComponentFactory.Create(ComServer, TTestAccess,
Class_TestAccess, ciMultiInstance, tmApartment);
end.
 
后退
顶部