Is there any chance of the TCustomMyDataSet class doesn't be threadsafe?

Discussion of open issues, suggestions and bugs regarding MyDAC (Data Access Components for MySQL) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
viniciusfbb
Posts: 11
Joined: Thu 07 Mar 2019 01:00

Is there any chance of the TCustomMyDataSet class doesn't be threadsafe?

Post by viniciusfbb » Thu 07 Mar 2019 01:26

Hello,

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;
And above the madExcept
Image

I am using the last version of the MyDac and the delphi Tokyo 10.2.3

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: Is there any chance of the TCustomMyDataSet class doesn't be threadsafe?

Post by ViktorV » Thu 07 Mar 2019 07:03

MyDAC is thread-safe, but the restriction is that you cannot use one connection (the TMyConnection component) in several threads, and you should use a separate connection in each thread.

viniciusfbb
Posts: 11
Joined: Thu 07 Mar 2019 01:00

Re: Is there any chance of the TCustomMyDataSet class doesn't be threadsafe?

Post by viniciusfbb » Thu 07 Mar 2019 11:14

ViktorV, Yes, I read about it, and each thread have it own connection.

My version of MyDAC don't have source, otherwise I could better investigate what happens in the destroy of the class "TMyStoredProc" and its classes relatives.

This problem always occurs in the destroy of it. Here is the debugger view (without mydac source, the callstack of the madExcept is better):

Image

Sorry for my bad english.

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: Is there any chance of the TCustomMyDataSet class doesn't be threadsafe?

Post by ViktorV » Thu 07 Mar 2019 12:17

Unfortunately, we can't reproduce the issue on the latest MyDAC 9.3.9
To understand the issue cause, we need a test sample where the issue is stably reproduced. As soon as we get such a sample, and if the cause of the issue is in the code of our product, we will try to fix it as soon as possible.
Therefore, please compose a small sample demonstrating the described behavior and send it to us using the contact form https://devart.com/company/contactform.html, including scripts for creating and filling database objects.

viniciusfbb
Posts: 11
Joined: Thu 07 Mar 2019 01:00

Re: Is there any chance of the TCustomMyDataSet class doesn't be threadsafe?

Post by viniciusfbb » Thu 14 Mar 2019 00:51

Problem solved.

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: Is there any chance of the TCustomMyDataSet class doesn't be threadsafe?

Post by ViktorV » Thu 14 Mar 2019 14:08

It is good to see that the problem has been solved.
Feel free to contact us if you have any further questions about our products.

Post Reply