| Autor |
Beitrag |
Tana´Ri
      
Beiträge: 230
|
Verfasst: Di 25.03.03 11:54
Hi,
so sieht zur zeit meine attach procedure aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| if not dataset.Active then dataset.Open; if (dataset.CanModify) then try dataset.Append; dataset.FieldValues['KontaktVorname']:=getPCName+' '+inttoStr(counter); dataset.FieldValues['KontaktNachname']:='ID_'+inttostr(ThreadID); dataset.Post;
except dataset.UpdateAction(TBasicAction(uaRetry)); if dataset.Active then dataset.Close; end; |
nun ich erzeuge mehrere Instanzen und lasse diese auf die datenbank (Access 2000) zugreifen bzw. schreiben. ich habe ein thread erstellt, von dem ich in meinem Form mehrere Instanzen erzeuge. Diese Tragen nur daten ein, nach undefinierbare Zeit kommt es zu einem Fehler, die Meldung lautet das auf aktuellen datensatz nicht zugegriffen werden kann da dieser zur zeit gesperrt sei, dadurch gehen datensätze verloren, da diese dann nicht eingetragen werden. Append bedeutet doch normal anhängen der daten, wie kann da ein datensatz gesperrt sein ???
HILFE !!! dieses Problem ärgert mich schon ne geraume zeit ich hoffe hier kann mir mal einer helfen.
* dies soll bei fehler die aktion erneut starten besser wäre natürlich ein preventives mittel.
ps: wichtig wäre vielleicht anzumerken das ich kein TADOConnection oder Command oder Table oder Query benutze, ich nutze nur das DataSet Objekt (genau: TBetterADODataSet 4.02)
Provider Jet Engine 4.0
Access 2000
Platform Win2k Sp3
MDAC 2.6
_________________ mfg
Tana´Ri
|
|
MSCH
      
Beiträge: 1448
Erhaltene Danke: 3
W7 64
XE2, SQL, DevExpress, DevArt, Oracle, SQLServer
|
Verfasst: Di 25.03.03 18:57
Ich hab das das auch mal gehabt; vieleicht hilfts dir, setzte im Objektinspektor den Cursor auf Server. Wenn du mehrere Threads am laufen hast, kriegst du eh Probleme mit dem ganzen Synchronisieren, deine Fehlermeldung spricht dafür, dass zwei Funktionen gleichzeitig auf ein und denselben Datensatz zugreifen. Was spricht dagegen das via sql mit insert zu machen?
grez
msch
|
|
Tana´Ri 
      
Beiträge: 230
|
Verfasst: Mi 26.03.03 08:47
hi MSCH,
so sieht meine Standardkonfiguration aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure Thr_BADODataset.SetStandardConfig; begin if dataset.Active then dataset.close; with DataSet do begin CursorLocation:=clUseServer; CursorType:=ctkeyset; CommandType:=cmdTableDirect; LockType:=ltPessimistic; CommandText:='Tablename'; end; if not dataset.Active then dataset.Open; end; |
wieso nicht SQL ? Nun ich habe auch eine Variante mit Sql gebastelt, eigentlich bin ja gerade dabei alles mal zu testen und verschiedene Wege zu versuchen. Ich habe gelesen das diese Problematik, also meine, durch das AutoIncFeld in meiner Access-Datenbank bedingt sei. In wiefern oder sogar einen Lösungvorschlag habe ich diesbezüglich noch nicht gefunden.
Ich habe das Ganze in als ein Thread erstellt sodas ich eine MultiUserUmgebung simulieren kann, im Form erzeuge ich einfach soviele ich will, aber nur weil 'User' gleichzeitig in die Datenbank schreiben wollen, darf dies in einer ordenlichen Anwendung nicht passieren, ich hoffe du verstehst was ich meine.
Später sollen Daten natürlich nicht nur per Append in die Datenbank gelangen, nein auch Edit, insert, sql ... alles sollte funktionieren und das fehlerfrei. Ich denke, wenn es mir gelingt diesen Fehler hier in den Griff zubekommen so mag er auch bei den anderen Variationen des Datenzugriffs keine Rolle mehr spielen.
Vielleicht kommt dann noch ein Problem dazu, denn ich muss anschließend die Stabilität noch in real-lan testen, d.h. wenn wirklich mehrere PC´s auf die Datenbank (Access-Tabelle) zugreifen. Ich hatte das sogar mal kurz getestet, dabei hat es mir irgendwie die Datenbank zersört, musste immer reparieren (dies könnte allerdings am selben Üroblem liegen)
thx MSCH
_________________ mfg
Tana´Ri
|
|
Tana´Ri 
      
Beiträge: 230
|
Verfasst: Do 27.03.03 10:13
Titel: allgemeines ADO Probleme ?
Hi leute,
solangsam gehen mir die Ideen aus, ich weiss nicht was an dem Code falsch ist, jedenfalls ob ich nun mit dem ADO- Dataset oder mit dem Command oder Query benutze, immer bekomme ich diesen aktualisierungs fehler wegen der sperre.
In der ATTACH Procedure habe ich diese verschiedenen Verfahren ausprobiert und nix wirkt
Im Moment steht im Code noch die version mit query, ich poste hier mal meine gesammten code des testprogramms. Es mag wohl unschönheiten beinhalten .... aber vielleicht hilfts.
Mein Programm läuft auf local C: und mein Tabelle liegt im lan auf einem anderen rechner K:
Grob nochmal das Prob:" Mehrfachzugriff "
(wenn ich nur eine Instanz habe funktioniert es [alles])
*es mag sein das einiges unbekannt sei (units), oder ander dinge sind ausgeklammert .. das sollte jedoch nicht vom wesentlichen ablenken (hinsichtlich ADO irrelevant)
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Contnrs, Dialogs, DB, ADODB, BetterADODataSet, StdCtrls, Mask, DBCtrls,thr_betteradodataset, TCIDebug_101, DBClient;
type Te = class(TForm) Label1: TLabel; ComboBox1: TComboBox; Memo1: TMemo; Label2: TLabel; Label3: TLabel; ADOQuery1: TADOQuery; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private Better_ADO_DataSet : Thr_BADODataset; ObjList,objlistDebugWin : TObjectlist; winbool:boolean;
public end;
const NUMBER_OF_THRBETTERADODATASET = 10;
var Form1 : Te;
implementation
{$R *.dfm}
procedure Te.FormCreate(Sender: TObject); var j,i:integer; filename:string; fwork : ComboArray; begin ObjList := TObjectlist.Create(false); objlistDebugWin := TObjectlist.Create(True); for i:=1 to NUMBER_OF_THRBETTERADODATASET do begin for j:=0 to 3 do fwork[j]:=A; filename:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=K:\DBSFOLDER\TestADO\MyDB.mdb;Mode=ReadWrite;Persist Security Info=False'; Better_ADO_DataSet := Thr_BADODataset.Create(false,handle,NIL,filename,NIL,fwork);
combobox1.Items.Add(IntToStr(Better_ADO_DataSet.ThreadID)); ObjList.Add(Better_ADO_DataSet); end; label1.caption:='Startzeit: '+timetostr(NOW); end;
procedure Te.FormDestroy(Sender: TObject); var i:word; begin for i:=0 to objlist.Count-1 do begin if (ObjList.Items[i] is Thr_BADODataSet) then with (Objlist.Items[i] as Thr_BADODataSet) do begin try Terminate; Waitfor; if assigned(fwin) then fwin:=NIL; finally Free; end; end; end; ObjList.Free; objlistDebugWin.Free; end;
end. |
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291:
|
unit thr_betteradodataset;
interface
uses Windows, SysUtils, Classes, ADODB, BetterADODataset, StdCtrls, TCIDebug_101, ComObj, DB, DBClient;
const RANDOMWERT = 10;
type TThisWork = (R,W,A,SQL,Nothing); ComboArray = array [0..3] of TThisWork;
type Thr_BADODataset = class(TThread) private query : TADOQuery; DataSet : TBetterADODataSet; counter,maxcount : cardinal; checkbool : boolean; flist : string; operation : ComboArray; howner:hwnd; procedure mySleep(NumberOfSeconds:LongWord); procedure Attach; procedure Read; procedure SQLRead; procedure Write; procedure DataSetStandardConfig; function getPCName : ShortString; public fwin : TDebugWin; Constructor Create(CreateSuspended: Boolean; Owner : hwnd; Conn : TADOConnection; Const TCI_CONNECTIONSTRING : string; myShow : TDebugWin; WorkType : ComboArray); Destructor Destroy; Override; property list : string read flist; property count : cardinal read counter; property max : cardinal read maxcount; protected procedure Execute; override; published
end;
implementation
uses Unit1;
procedure Thr_BADODataset.Execute; var i:byte; begin flist:='ThreadId '+inttostr(threadid)+'|'; repeat mySleep(1000+(random(RANDOMWERT)+1)); for i:=low(operation) to high(operation) do begin dataset.close; case operation[i] of R : read; A : Attach; W : write; SQL : SQLRead; Nothing : mysleep(100); end; mySleep(1000+(random(RANDOMWERT)+1)); if checkbool then flist:=flist+'T'+inttostr(counter)+'|' else if not checkbool then flist:= flist+'F'+inttostr(counter)+'|'; end; until terminated;
end;
procedure Thr_BADODataset.SQLRead; begin try dataset.Close; dataset.CommandType:=cmdtext; dataset.CommandText:='SELECT [Kunden-Nr] FROM Kunden'; dataset.Open; try dataset.Requery; try if dataset.Recordset.RecordCount>0 then while not dataset.Eof do begin if not assigned(fwin) then break; fwin.Writeln([string(dataset.Recordset.Fields.Item[0].Value)]); if not dataset.FindNext then break; end; except end; finally DataSetStandardConfig; end; except beep; end; end;
procedure Thr_BADODataset.Write; var i,r:integer; begin try if dataset.recordcount<=0 then exit; inc(counter); r:=random(dataset.RecordCount-1); if counter > maxcount then maxcount:=counter; dataset.first; for i:=0 to r do dataset.FindNext; if (dataset.CanModify)AND(dataset.UpdateStatus<>usUnModified) then begin dataset.UpdateCursorPos; dataset.Recordset.Fields.Item[2].Value:='OVERRIDE '+getPCName+' '+inttoStr(counter); dataset.Recordset.Fields.Item[1].Value:='ID_'+inttostr(ThreadID); end; dataset.Last; except beep; end; end;
procedure Thr_BADODataset.Attach; var param1,param2:string; begin checkbool:=false; inc(counter); param1:=getPCName+' '+inttoStr(counter); param2:=inttostr(threadid); if counter > maxcount then maxcount:=counter; try query.Close; query.SQL.Clear; query.SQL.Add('INSERT INTO Kunden(KontaktNachname,KontaktVorname) VALUES ("'+param1+'","'+param2+'")'); query.ExecSQL; except end; end;
procedure Thr_BADODataset.Read; var i,j : word; buf :string; begin try buf:=''; if dataset.Recordset.RecordCount>0 then begin if not dataset.FindFirst then exit; for j:=0 to dataset.Recordset.RecordCount-1 do begin for i:=0 to dataset.Recordset.Fields.Count-1 do buf:=buf+' | '+string(DataSet.Recordset.Fields.Item[i].Value); if buf<>'' then if not assigned(fwin) then break else fwin.Writeln([buf]); buf:=''; if terminated then exit else dataset.FindNext; end; end; except beep; end; end;
Constructor Thr_BADODataset.Create(CreateSuspended: Boolean; Owner : hwnd; Conn : TADOConnection; Const TCI_CONNECTIONSTRING : string; myShow : TDebugWin; WorkType : ComboArray); var buffer:string; Procedure ConnectionStringDiaglog; begin Dataset.ConnectionString := PromptDataSource(0,''); end; begin inherited Create(CreateSuspended); operation := Worktype; counter:=0; maxcount:=0; fwin:=myShow; howner := owner;
DataSet:=TBetterAdoDataSet.Create(NIL); if Assigned(Conn) then DataSet.Connection:=Conn else begin if TCI_CONNECTIONSTRING<>'' then begin buffer:=pchar(@TCI_CONNECTIONSTRING[pos('Source=',TCI_CONNECTIONSTRING)+7]); buffer:=copy(buffer,1,pos(';',buffer)-1); end else buffer:=''; if FileExists(buffer) then dataset.ConnectionString:=TCI_CONNECTIONSTRING else begin ConnectionStringDiaglog; end; end; query := TADOQuery.Create(NIL); with query do begin ConnectionString:=dataset.ConnectionString; CursorLocation:=clUseServer; CursorType:=ctkeyset; LockType:=ltPessimistic; end; DataSetStandardConfig; end;
procedure Thr_BADODataset.DataSetStandardConfig; begin if dataset.Active then dataset.close; with DataSet do begin CursorLocation:=clUseServer; CursorType:=ctkeyset; CommandType:=cmdTableDirect; LockType:=ltPessimistic; CommandText:='Addressen'; end; if not dataset.Active then dataset.Open; end;
Destructor Thr_BADODataSet.Destroy; begin query.free; if dataset.Active then dataset.Close; DataSet.Free; inherited Destroy; end;
procedure Thr_BADODataSet.mySleep(NumberOfSeconds:LongWord); var i:word; begin for i:=0 to (NumberOfSeconds div 10) do if not Terminated then sleep(10) else break; end;
function Thr_BADODataset.getPCName : String; var buffer : array [0..21] of AnsiChar; dw : dword; begin dw:=high(buffer); GetComputerName(buffer,dw); result:=pchar(@buffer[0]); end;
INITIALIZATION randomize();
end. |
_________________ mfg
Tana´Ri
|
|
|