0

我正在开发基于 Indy 的应用程序。Server 有几个 Indy TCP Server 组件。所以它在多线程下工作并处理mysql db。我遇到了一个问题。那是关于线程中 MySQL DB 的异常。当多个线程攻击同一个数据库表时,它说我如下

UniQuery_Mgr: Duplicate field name 'id'
UniQuery_Mgr: Field 'grp_id' not found //of course grp_id field is really existed.
Assertion failure (C:\Program Files (x86)\unidac539src\Source\CRVio.pas, line 255)
Commands out of sync;  You can't run this command now
ReceiveHeader: Net packets out of order: received[0], expected[1]
UniQuery_Mgr: Cannot perform this operation on a closed dataset

我该怎么办?UniQuery_Mgr 是 TUniQuery 组件。我的查询处理代码通常是这样的

代码 1

  sql := 'SELECT * FROM data_writed;';//for example
  UniQuery_Mgr.SQL.Clear;
  UniQuery_Mgr.SQL.Add(sql);
  UniQuery_Mgr.ExecSQL;

代码 2

  try
    sql := 'SELECT * FROM gamegrp_mgr;';
    UniQuery_Mgr.SQL.Clear;
    UniQuery_Mgr.SQL.Add(sql);
    UniQuery_Mgr.ExecSQL;

    if UniQuery_Mgr.RecordCount > 0 then
    begin
      MAX_GAME_GROUP_COUNT := UniQuery_Mgr.RecordCount + 1;

      UniQuery_Mgr.First;
      i := 1;
      while not UniQuery_Mgr.Eof do
      begin
        Game_Group_ID[i] := UniQuery_Mgr.FieldByName('grp_id').AsInteger;
        Game_Game_ID[i] := UniQuery_Mgr.FieldByName('game_id').AsInteger;
        UniQuery_Mgr.Next;
        Inc(i);
      end;
    end;
  except
    on E : Exception do
    begin
      EGAMEMSG := Format('GAME group read error: <%s> @ %s',[ E.ToString, DateTimeToStr(now)]);
      Exit;
    end;
  end;

代码 3

  try
    sql := 'UPDATE data_writed SET write_gamegrp = ' + QuotedStr('0') + ';';
    UniQuery_Mgr.SQL.Clear;
    UniQuery_Mgr.SQL.Add(sql);
    UniQuery_Mgr.ExecSQL;
  except
    on E : Exception do
    begin
      EGAMEMSG := Format('data updating error: <%s> @ %s',[ E.ToString, DateTimeToStr(now)]);
      Exit;
    end;
  end;

我处理数据库组件不好?是否存在其他线程安全方法???

4

0 回答 0