Ir al contenido


Foto

Acceso concurrente en acces con odbc

Base de datos Acces Odbc Lazarus

  • Por favor identifícate para responder
1 respuesta en este tema

#1 csandoval

csandoval

    Newbie

  • Miembros
  • Pip
  • 1 mensajes

Escrito 22 febrero 2019 - 04:16

Muy buen dia.

Soy nuevo en la comunidad y como todos me acerco a ustedes en busca de conocimiento, actualmente me encuentro desarrollando una aplicacion para la oficina misma que es utilza por al menos 5 usuarios de forma simultanea, estoy utilizando como base de datos MICROSOFT ACCES debido a que es la base que tienen instalados todos los quipos pero al momento de escribir de forma concurrente en la base esta se bloquea por el primer usuario que lo intenta.

he abierto el archivo de la base de datos directamente desde ACCES y escrito en el de forma simultanea en mas de un quipo, por lo que concluyo que el problema esta en mi forma de interactuar ACCES desde LAZARUS, enseguida les comparto un extracto del programa donde se pueden ver las interacciones que tengo con la base de datos y las configuracones generales:

-La conexion se realza mediante ODBC.
-Se inicializa el ODBCConn con un DSN de sistema que apunta al archivo .accdb.
-los componentes transaction y query tienen como DATABASE al ODBCConn.
-La propiedad Action del transaction tiene como parametro caCommit.
-El Query tiene inhabilitado el campo UsePrimaryKey.

Enseguida parte del codigo:

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
ODBCConnection1.Connected:=False;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
ODBCConnection1.Connected:=True;
end;


//La siguiente funcion busca un ndice y s no exste lo registra.

Function TForm1.fncBDObtieneID(strTabla : String; strCampo : String; strValor : String) : Integer;
var
bolEncontrado : Boolean;
begin
fncBDObtieneID := -1;
While(fncBDObtieneID = -1) do
begin
SQLQuery1.SQL.Text := 'SELECT * FROM ' + strTabla + ' WHERE ' + strCampo + ' = :VALOR;';
SQLQuery1.Prepare;
SQLQuery1.Params.ParamByName('VALOR').AsString := strValor;
SQLQuery1.Open;
bolEncontrado := False;
while not SQLQuery1.Eof do
begin
If SQLQuery1.FieldByName(strCampo).AsString = strValor Then
begin
bolEncontrado := True;
fncBDObtieneID := SQLQuery1.FieldByName('ID').AsInteger;
end;
SQLQuery1.Next;
end;
SQLQuery1.Close;
SQLQuery1.Clear;
If Not bolEncontrado Then
begin
SQLQuery1.SQL.Text := 'INSERT INTO ' + strTabla + '(' + strCampo + ') VALUES(:VALOR);';
SQLQuery1.Prepare;
SQLQuery1.Params.ParamByName('VALOR').AsString := strValor;
SQLQuery1.ExecSQL;
SQLQuery1.Close;
end;
end;
end;


//

procedure TfrmPrincipalSHMC.btnCarrpsPruebasProcesarClick(Sender: TObject);
var
strTren : String;
lstDatosDeTren : TStringList;
intFor : Integer;
begin
lstDatosDeTren := TStringList.Create;
lstDatosDeTren.CommaText:=fncBuscaTrenQueSitue(tbxCarrosSituarEstacion.Text);
strTren := lstDatosDeTren.Strings[0] + ' ' + lstDatosDeTren.Strings[1];
If fncSituaListaConTren(strTren,lstDatosDeTren.Strings[2],tbxCarrosSituarEstacion.Text,tbxCarrosSituaZVP.Text,tblCarrosSituarUnidades) Then
begin

end;
for intFor := 0 To (tblCarrosSituarUnidades.RowCount -2) do begin
If (fncObtieneCodigoDeCarro(tblCarrosSituarUnidades.Cells[0,intFor + 1], tblCarrosSituarUnidades.Cells[1,intFor + 1]) = 'SC') Or (fncObtieneCodigoDeCarro(tblCarrosSituarUnidades.Cells[0,intFor + 1], tblCarrosSituarUnidades.Cells[1,intFor + 1]) = 'DT') Then
begin
tblCarrosSituarUnidades.Cells[2,intFor + 1] := 'OK';
intIDCarro := fncCarroObtieneID(tblCarrosSituarUnidades.Cells[0,intFor + 1] + tblCarrosSituarUnidades.Cells[1,intFor + 1]);
SQLQuery1.SQL.Text := 'INSERT INTO UCARROSSITUADOS(IDFUSUARIO, IDFCARRO) VALUES(:intUsuario, :intCarro);';
SQLQuery1.Prepare;
SQLQuery1.Params.ParamByName('intUsuario').AsInteger := intIDUsuario;
SQLQuery1.Params.ParamByName('intCarro').AsInteger := intIDCarro;
SQLQuery1.ExecSQL;
SQLQuery1.Close;
end
else
begin
tblCarrosSituarUnidades.Cells[2,intFor + 1] := 'ERROR';
end;
end;
end;


Las anteriores son las funciones con las que interactuo con la base de datos, les explico nuevamente el flujo de eventos que produce el bloqueo.

Usuario 1 inicia la aplicacion y ejecuta el evento click antes mencionado.
Usuario 2 ejecuta la aplicacon y ejecuta el evento click antes mencionado obteniendo como resultado un mensaje de error que indica que Usuario 1 tiene bloquada la base de datos.

Espero les sea de utilidad la informacion proporcionada y de ser necesario algo mas se los proporcionare con gusto.

Quedo en espera de sus amables respuestas
  • 0

#2 Kenddy Reinardo Bello

Kenddy Reinardo Bello

    Newbie

  • Miembros
  • Pip
  • 3 mensajes

Escrito 13 abril 2019 - 01:24

Buenas espero que este ejemplo te pueda ayudar:
 
 

 

delphi
  1. unit Unit1;
  2.  
  3.  
  4. {$mode objfpc}{$H+}
  5.  
  6.  
  7. interface
  8.  
  9.  
  10. uses
  11.   Classes, SysUtils, db, odbcconn, sqldb, Forms, Controls, Graphics, Dialogs,
  12.   StdCtrls, ExtCtrls, DBGrids, ZConnection, ZDataset;
  13.  
  14.  
  15. type
  16.  
  17.  
  18.   { TForm1 }
  19.  
  20.  
  21.   TForm1 = class(TForm)
  22.     Button1: TButton;
  23.     Button2: TButton;
  24.     Button3: TButton;
  25.     Button4: TButton;
  26.     Button5: TButton;
  27.     DS1: TDataSource;
  28.     DBGrid1: TDBGrid;
  29.     EditBuscar: TEdit;
  30.     Editcodigo: TEdit;
  31.     Editnombre: TEdit;
  32.     Editdireccion: TEdit;
  33.     GroupBox1: TGroupBox;
  34.     Label1: TLabel;
  35.     Label2: TLabel;
  36.     Label3: TLabel;
  37.     Panel1: TPanel;
  38.     Conecion: TZConnection;
  39.     Qry1: TZQuery;
  40.     Qry1codigoid: TLongintField;
  41.     Qry1direccion: TStringField;
  42.     Qry1nombre: TStringField;
  43.     procedure Button1Click(Sender: TObject);
  44.     procedure Button2Click(Sender: TObject);
  45.     procedure Button3Click(Sender: TObject);
  46.     procedure Button4Click(Sender: TObject);
  47.     procedure Button5Click(Sender: TObject);
  48.     procedure DBGrid1DblClick(Sender: TObject);
  49.     procedure FormShow(Sender: TObject);
  50.   private
  51.       procedure RefrescarDatos;
  52.       procedure BusquedaRapida;
  53.   public
  54.  
  55.  
  56.   end;
  57.  
  58.  
  59. var
  60.   Form1: TForm1;
  61.  
  62.  
  63. implementation
  64.  
  65.  
  66. {$R *.lfm}
  67.  
  68.  
  69. procedure TForm1.FormShow(Sender: TObject);
  70. begin
  71.   RefrescarDatos;
  72. end;
  73. procedure TForm1.BusquedaRapida;
  74. begin
  75.   If editBuscar.Text='' then
  76.      begin
  77.        MessageDlg('Escriba el Nombre que desea Buscar',mtInformation,[MbOK],0);
  78.        editBuscar.SetFocus;
  79.      end;
  80.   Qry1.SQL.Clear;
  81.   Qry1.SQL.Text := 'SELECT * FROM Empresa WHERE nombre ="&'+EditBuscar.text+'&"';
  82.   qry1.Open;
  83.  
  84.  
  85. end;
  86.  
  87.  
  88. procedure TForm1.Button1Click(Sender: TObject);
  89.   begin
  90.       if (editnombre.Text='')or
  91.       (editdireccion.Text='')then
  92.       begin
  93.         MessageDlg('Los Campos no deben estar en Blanco',mtinformation,[mbok],0);
  94.         exit
  95.       end;
  96.    qry1.SQL.Clear;
  97.    qry1.SQL.Text:='INSERT INTO Empresa(nombre,direccion)VALUES(:B, :C)';
  98.    Qry1.Params[0].Value:=EditNombre.Text;
  99.    Qry1.Params[1].Value:=EditDireccion.Text;
  100.    qry1.ExecSQL;
  101.    RefrescarDatos;
  102.    ShowMessage('Datos Guardados Correctamente');
  103.    editnombre.SetFocus;
  104.  
  105.  
  106. end;
  107.  
  108.  
  109. procedure TForm1.Button2Click(Sender: TObject);
  110.  begin
  111.     if (editnombre.Text='')or
  112.       (editdireccion.Text='')then
  113.       begin
  114.         MessageDlg('Los Campos no deben estar en Blanco',mtInformation,[mbok],0);
  115.         exit
  116.       end;
  117.    Qry1.SQL.Clear;
  118.    Qry1.SQL.Text:='UPDATE Empresa SET nombre=:B, direccion=:C WHERE codigoid=:A';
  119.    Qry1.Params[0].Value:=EditNombre.Text;
  120.    Qry1.Params[1].Value:=Editdireccion.Text;
  121.    Qry1.Params[2].Value:=EditCodigo.Text;
  122.    Qry1.ExecSQL;
  123.    RefrescarDatos;
  124.    ShowMessage('Datos Modificados Correctamente');
  125.    editnombre.SetFocus;
  126. end;
  127.  
  128.  
  129. procedure TForm1.Button3Click(Sender: TObject);
  130. begin
  131.   RefrescarDatos;
  132. end;
  133.  
  134.  
  135. procedure TForm1.Button4Click(Sender: TObject);
  136.   begin
  137.      if (editnombre.Text='')or
  138.       (editdireccion.Text='')then
  139.       begin
  140.         MessageDlg('Los Campos no deben estar en Blanco',mtinformation,[mbok],0);
  141.         exit
  142.       end;
  143.    qry1.SQL.Clear;
  144.    Qry1.SQL.Text := 'DELETE FROM Empresa WHERE codigoid =:A';
  145.    Qry1.Params[0].Value:= EditCodigo.Text;
  146.    qry1.ExecSQL;
  147.    RefrescarDatos;
  148.    ShowMessage('Dato Eliminado Correctamente');
  149.    editnombre.SetFocus;
  150. end;
  151.  
  152.  
  153. procedure TForm1.Button5Click(Sender: TObject);
  154. begin
  155.   BusquedaRapida;
  156. end;
  157.  
  158.  
  159. procedure TForm1.DBGrid1DblClick(Sender: TObject);
  160. begin
  161.    editCodigo.Text:=DBGrid1.DataSource.DataSet.FieldByName('codigoid').AsString;
  162.    editNombre.Text:=DBGrid1.DataSource.DataSet.FieldByName('nombre').AsString;
  163.    editdireccion.Text:=DBGrid1.DataSource.DataSet.FieldByName('direccion').AsString;
  164. end;
  165.  
  166.  
  167. Procedure TForm1.RefrescarDatos;
  168. begin
  169.    Qry1.SQL.Clear;
  170.    Qry1.SQL.Add('SELECT * FROM Empresa');
  171.    qry1.Open;
  172.  
  173.  
  174.    editcodigo.Text:='Automatico';
  175.    editnombre.Text:='';
  176.    editdireccion.Text:='';
  177.    editBuscar.Text:='';
  178.    editnombre.SetFocus;
  179. end;
  180.  
  181.  
  182. end.

 

Con este codigo te presento el formulario completo para mejor guia
  • 0





Etiquetado también con una o más de estas palabras: Base de datos, Acces, Odbc, Lazarus

IP.Board spam blocked by CleanTalk.