Pregunta

Tengo un servidor con estos códigos:

procedure TFrmMain.TCPServerExecute(AContext: TIdContext);
begin
      Res := DoRegister(Name,Family,Username,Password);
end;

function TFrmMain.DoRegister(Name,Family,Username,Password:string): bool;
var
  Qry: TSQLQuery;
begin
  Qry := TSQLQuery.Create(nil);
  try
    Qry.SQLConnection := FrmConnect.SQLConnection;
    Qry.SQL.Text :='INSERT INTO `table` ...';
    Qry.ExecSQL();
  finally
    Qry.Free;
  end;
  Result := True;
end;

¿hay algún problema con el acceso a una tabla en diversos hilos? y totalmente lo que es peligroso para ser utilizado en caso Onexecute?

Gracias por amigos de respuesta.

Por lo tanto, es una verdadera forma de hacer diferentes conexiones para diferentes hilos?

var
  Qry: TSQLQuery;
  SqlCon: TSQLConnection;
Begin
  SqlCon := TSQLConnection.Create(nil);
  Qry := TSQLQuery.Create(nil);
  try
    SqlCon := FrmConnect.SQLConnection;
    Qry.SQLConnection := SqlCon;
  finally
    SqlCon.Free;
    Qry.Free;
  end;
end;
¿Fue útil?

Solución

Su segundo fragmento de código no es correcto. Se desea sobreescribir la nueva conexión con la conexión global, cuando debería estar copiando a cabo la cadena de conexión. También está liberando que global que probablemente causar problemas para el resto de su aplicación. Algo como esto, dependiendo de los detalles de su clase TSQLConnection:

SqlCon := TSQLConnection.Create(nil); // create
Qry := TSQLQuery.Create(nil);
try
  //SqlCon := FrmConnect.SQLConnection; // overwrite!!!
  SqlCon.ConnectionString :=  FrmConnect.SQLConnection.ConnectionString;
  SqlCon.Active := true;
  Qry.SQLConnection := SqlCon;
  ...

Si usted quiere tener un pool de conexiones DATABSE es bastante complicado porque las conexiones son por lo general hilo específico - que necesita una por hilo y no se puede pasar de ellos entre los hilos. Así que terminan escribir mucho código de apoyo que.

Ahora utilice el OmniThreadLibrary y tener un método de fábrica que devuelve una nueva conexión de base de datos. Eso me da un grupo de subprocesos que me alimento tareas en, por lo que mi tarea específica se une a un tema existente cuando se ejecuta, pero el hilo es bastante vivieron largo. El código que tenía que escribir para conseguir esto es muy pequeña (estoy usando ADO):

type
    // a factory to generate new instances of our thread-specific data
    IThreadPoolData = interface
        ['{14917B01-6613-4737-B87E-0046789D4284}']
        function GetConnection: TADOConnection;
        function GetStoredProc: TADOStoredProc;
    end;

    TThreadPoolData = class(TInterfacedObject, IThreadPoolData)
    strict private
        FADOConnection: TADOConnection;
        FStoredProc: TADOStoredProc; // lazy creation!
    public
        constructor Create(aConnectionString: string); overload;
        destructor Destroy; override;
        function GetConnection: TADOConnection;
        function GetStoredProc: TADOStoredProc;
    end;

// create the connection here so thread creation is slow but using it 
// is (relatively) fast

constructor TThreadPoolData.Create(aConnectionString: string);
begin
    FADOConnection := TADOConnection.Create(nil);
    FADOConnection.LoginPrompt := false;
    FADOConnection.ConnectionString := aConnectionString;
    FADOConnection.ConnectOptions := coAsyncConnect;
    FADOConnection.Connected := true;
end;

destructor TThreadPoolData.Destroy;
begin
    FADOConnection.Connected := false;
    if assigned(FStoredProc) then
        FreeAndNil(FStoredProc);
    FreeAndNil(FADOConnection);
end;

Usted tendrá que hacer algo similar si usted escribe su propia agrupación de hebras o conexión.

Otros consejos

Cada hilo acceso a base de datos debe tener su propia conexión, no se puede compartir una conexión de base de datos entre varios hilos. OnExecute evento es invocado en el contexto de la rosca que corresponde al cliente solicitante, por lo que cada vez que se invoca, se ejecuta dentro de un subproceso de trabajo, y un hilo tan debe tener su propia conexión DB.

Si no desea establecer una nueva conexión para cada subproceso de trabajo; una opción podría ser, dedicar un solo hilo para la conexión DB y delegar todas las operaciones de base de datos a ese tema, por ejemplo, sus otros hilos pueden enviar sus declaraciones SQL de inserción a una cola en ese hilo DB y DB que se ejecuta hilo ellos de uno por uno utilizando una sola conexión de DB. Por supuesto, si usted toma este enfoque, toda la carga DB sería en un solo hilo, y si usted tiene tantas operaciones de base de datos, a continuación, que DB hilo en sí podría ser un cuello de botella! Lo que es más, este enfoque, las ejecuciones de consulta serían asíncrono excepto que utiliza una técnica de sincronización cada vez que cada uno de sus hilos piden el hilo DB para ejecutar una consulta DB para ellos.

Asimismo, tomamos nota de que si sus componentes de acceso DB son ADO, entonces usted tiene que llamar a CoInitialize y CoUninitialize, porque Delphi tiempo de ejecución sólo se hace para que el hilo principal no otros hilos que son creados por ti.

Yo usaría un conjunto de conexiones para las conexiones de bases de datos. Cada hilo entonces sólo solicita una conexión de la agrupación cuando sea necesario (que podría bloquear si hay conexiones actualmente hay libres en el grupo) y luego usos y finalmente lo devuelve a la piscina. Una piscina tiene la ventaja de que hay menos conexiones necesarias que hay hilos concurrentes, y las conexiones ya están presentes cuando sea necesario.

Sí y no. Puede acceder a una sola tabla de diferentes temas, pero se necesita una instancia TSQLConnection por hilo para hacerlo con seguridad.

Actualizar

Instantiating una conexión diferente para cada hilo está bien. Es lo que la mayoría de las páginas web hacen todo el tiempo, así (script del lado del servidor mediante ASP, PHP o medios de ejecución ... menos por el estado y por lo tanto las conexiones generalmente no sobreviven a la siguiente solicitud y tienen que ser re-establecido).

Si está preocupado por la sobrecarga, se puede considerar el uso de una única conexión como vcldeveloper sugiere. Tendrá que asegurarse de que cualquier variables y campos miembros utilizados por que "rosca de conexión", que son modificados por los otros hilos (por ejemplo, el miembro de campo que recibe el SQL que se ejecutará), tendrán que ser protegidos por algún tipo de mecanismo de sincronización .

Lo mismo se aplica a la agrupación de conexiones según lo sugerido por mjustin, aunque en ese caso, las necesidades del conjunto de conexiones a estar protegidos por mecanismos de sincronización.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top