我有以下问题:
1)我使用Delphi XE7开发一个3层系统。
2)使用REST使用datasnap创建的服务器层。
3)我使用Firebird作为数据库,并使用FireDAC进行访问。
4)我有一个值 01 的序列。
5)我在服务器层创建了以下查询:
从rdb $ database中选择GEN_ID(gen_my_sequence,1)
6)在服务器上返回查询中的序列值: 02 。
7)但是客户端层返回03。
我不明白为什么查询会被执行两次。
任何人都可以帮助我吗?
答案 0 :(得分:1)
这是firebird中生成器(序列)的本质。每次请求时它们的值都会增加,并且生成器的值会从该请求更新并保持更新。发电机也在交易控制之外。 见firebirdsql generatorguide-basics。你要求的地方并不重要。
答案 1 :(得分:1)
我使用Embarcadero指出的技术标准。
我意识到这一点:
1) TFDJSONInterceptor.ItemListToJSONObject 例程中的 Data.FireDACJSONReflect 单元具有以下代码块:
if not LActive then
LDataSet.Active := True;
try
LJSONDataSet := DataSetToJSONValue(LDataSet);
// Use AddPair overload that will accept blank key
AJSONObject.AddPair(TJSONPair.Create(LPair.Key, LJSONDataSet))
finally
if not LActive then
LDataSet.Active := False;
end;
看到他激活一次查询,导致序列递增。
但是在 DataSetToJSONValue(LDataSet)例程中;这段代码是:
if (LMemTable = nil) then
begin
LMemTable := TFDMemTable.Create(nil);
LAdapter := TFDTableAdapter.Create(nil);
LMemTable.Adapter := LAdapter;
LAdapter.SelectCommand := ADataSet.Command;
LMemTable.Active := True;
end;
再次看到他激活查询,其中序列再次递增。
现在我不知道我是犯了错误还是错误,但是我创建了一个继承自 TFDMemTable 的新类,并认为这个类中有一些错误,但是做了一个测试使用 TFDMemTable 组件,FireDAC的标准组件,即使这样,任何查询的激活也会执行两次,因为代码不考虑这两个类中的任何一个,如 TFDCustomMemTable ,即使它们是直接从这个班继承的。
我评论了 DataSetToString例程(const ADataSet:TFDAdaptedDataSet)的代码,如下所示:
LMemTable := nil;
LAdapter := nil;
try
//if (ADataSet is TFDCustomMemTable) then
LMemTable := TFDCustomMemTable(ADataSet);
{if (LMemTable = nil) then
begin
LMemTable := TFDMemTable.Create(nil);
LAdapter := TFDTableAdapter.Create(nil);
LMemTable.Adapter := LAdapter;
LAdapter.SelectCommand := ADataSet.Command;
LMemTable.Active := True;
end;}
通过这种方式解决了问题,应用程序的性能似乎有所提高。