I'm making a high-performance multithread server where there can be up to 100,000 concurrent connections. And, during my performance tests, I sometimes got the same exception, by destroying the TCustomMyDataSet class.
This happens with a certain rarity, more or less every 100,000 request-response, so I came to believe that it could be a multithreading problem of the TCustomMyDataSet classes (TMyStoredProc base class, among others).
The following code is the only function I use during my tests, which is the call of a database stored procedure, which returns the data of an address:
Code: Select all
procedure TipServerDatabase.GetPostalCodeData(ACountryCode, APostalCode: TipNullable<string>; out APostalCodeAddress, APostalCodeDependentLocality, APostalCodeLocalityDistrict, APostalCodeLocality, APostalCodeAdministrativeArea: TipNullable<string>);
var
LConnection: TMyConnection;
LStoredProc: TipMyStoredProc;
LStopwatch: TipStopwatchLite;
begin
LConnection := GetConnection;
try
LStoredProc := TipMyStoredProc.Create(LConnection);
try
LStoredProc.Connection := LConnection;
LStoredProc.StoredProcName := 'get_postal_code_data';
LStoredProc.PrepareSQL;
try
if ACountryCode.IsNull then
LStoredProc.ParamByName('in_country_code').Clear
else
LStoredProc.ParamByName('in_country_code').AsString := ACountryCode.Value;
if APostalCode.IsNull then
LStoredProc.ParamByName('in_postal_code').Clear
else
LStoredProc.ParamByName('in_postal_code').AsString := APostalCode.Value;
LStopwatch := TipStopwatchLite.StartNew;
LStoredProc.Execute;
try
DoCallFetched(LStoredProc.StoredProcName, LStopwatch.Miliseconds / 1000);
if LStoredProc.FieldByName('@out_postal_code_address').IsNull then
APostalCodeAddress.IsNull := True
else
APostalCodeAddress.Value := string(LStoredProc.FieldByName('@out_postal_code_address').AsString);
if LStoredProc.FieldByName('@out_postal_code_dependent_locality').IsNull then
APostalCodeDependentLocality.IsNull := True
else
APostalCodeDependentLocality.Value := string(LStoredProc.FieldByName('@out_postal_code_dependent_locality').AsString);
if LStoredProc.FieldByName('@out_postal_code_locality_district').IsNull then
APostalCodeLocalityDistrict.IsNull := True
else
APostalCodeLocalityDistrict.Value := string(LStoredProc.FieldByName('@out_postal_code_locality_district').AsString);
if LStoredProc.FieldByName('@out_postal_code_locality').IsNull then
APostalCodeLocality.IsNull := True
else
APostalCodeLocality.Value := string(LStoredProc.FieldByName('@out_postal_code_locality').AsString);
if LStoredProc.FieldByName('@out_postal_code_administrative_area').IsNull then
APostalCodeAdministrativeArea.IsNull := True
else
APostalCodeAdministrativeArea.Value := string(LStoredProc.FieldByName('@out_postal_code_administrative_area').AsString);
finally
LStoredProc.Close;
end;
except
on E: EDatabaseError do
raise EipDatabase.CreateFmt(CALL_ERROR, [E.Message, LStoredProc.StoredProcName]);
else
raise;
end;
finally
LStoredProc.Free;
end;
finally
if MultiConnection then
LConnection.Free;
end;
end;
I am using the last version of the MyDac and the delphi Tokyo 10.2.3