[Delphi 5] Multi-User & Transactions

Pagina: 1
Acties:
  • 151 views sinds 30-01-2008
  • Reageer

  • marenk_vos
  • Registratie: Augustus 2001
  • Laatst online: 23-07 13:21
Ik heb een klein basis programmaatje gemaakt alleen om mijzelf te leren omgaan met transactions, interbase en delphi 5. Nu zit ik met het probleem dat als ik in het ene programma een wijziging heb aangebracht dat het in het andere programma niet zichtbaar is. Ik heb hiervoor al gekeken op community.borland.com maar daar kan ik geen goed antwoordvinden:

borland:

All changes made to the database must be committed before the changes can be visible to others. When another user actually sees the committed changes depends on the transaction isolation level they are using. If another user is using snapshot isolation he/she will not see the change until he/she commits and starts a new transaction. If he/she is using read committed isolation he/she will see the change the nest time he/she selects the changed record.

Wat heb ik dan in onderstaande code fout gedaan?

IK heb 2 forms, op form1 staat 1x ibdatabase, 1x ibtransaction, 1x ibtable, 1x tdatasource, 1x button1

op form1 staat 1x dbgrid, 1x button1

Form2:

code:
1
2
3
4
5
6
7
8
9
10
11
12
procedure TForm2.FormShow(Sender: TObject);
begin
Form1.IBTable1.Open;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.IBTable1.edit;
form1.IBTable1PROJECTNR.value:=edit1.text;
Form1.IBTable1.Post;

end;


form1:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
procedure TForm1.FormCreate(Sender: TObject);
begin
IBDatabase1.Open;
IBTransaction1.StartTransaction;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
form2.Show;
end;

procedure TForm1.IBTable1AfterPost(DataSet: TDataSet);
begin
IBDatabase1.ApplyUpdates([ibtable1]);
IBTransaction1.CommitRetaining;
end;


Opmerking: Als ik starttransaction verplaats van de form1.create naar het begin van button1click op form2 dan krijg ik de foutmelding: Transaction is active. En als ik commitrataining verander in commit is mijn dbgrid leeg.....

Dell XPS 17 Intel i7 2630 Nvidia GT555 3Gb Hd1: OCZ Vertex 2 SSD 60 GB Hd2: 500Gb


  • johnny7
  • Registratie: November 2000
  • Laatst online: 07-11-2023
Moet je na het committen niet weer een nieuwe transactie starten om gegevens te kunnen laten zien van een tabel? :?

  • marenk_vos
  • Registratie: Augustus 2001
  • Laatst online: 23-07 13:21
Als ik in een 2e applicatie de record probeer te wijzigen die ik in de de 1e applicatie heb gewijzigd krijg ik een DEADLOCK error.....

Dell XPS 17 Intel i7 2630 Nvidia GT555 3Gb Hd1: OCZ Vertex 2 SSD 60 GB Hd2: 500Gb


  • whoami
  • Registratie: December 2000
  • Laatst online: 20:46
[nohtml]
marenk_vos schreef op 20 november 2002 @ 09:57:
Ik heb een klein basis programmaatje gemaakt alleen om mijzelf te leren omgaan met transactions, interbase en delphi 5. Nu zit ik met het probleem dat als ik in het ene programma een wijziging heb aangebracht dat het in het andere programma niet zichtbaar is. Ik heb hiervoor al gekeken op community.borland.com maar daar kan ik geen goed antwoordvinden:
Als je een transactie start, waarbinnen je gegevens gaat gaan updaten, dan kan jij die updates wel al zien voordat de transactie gecommited is, maar een andere user (die een andere connectie heeft naar de db) kan de nog niet gecommitte wijzigingen niet zien.
code:
1
2
3
4
5
6
db.StartTransaction();
//do some updates
qryInsert.ExecSQL();
// hier is het nieuwe record nog niet zichtbaar voor andere sessies.
db.Commit();
// vanaf hier wel.
Wat heb ik dan in onderstaande code fout gedaan?
Ik zie wel dat je je transactie commit, maar ik vind de manier waarop je het doet niet zo mooi.

Je laat de transactie best zo min mogelijk lang duren, dus, als je een knop 'Save' hebt, zet je in de OnClick van die knop best code om de transactie te beginnen, om de gegevens te posten en om de transactie te committen/rollbacken.

https://fgheysels.github.io/


  • Aetje
  • Registratie: September 2001
  • Laatst online: 18-12-2025

Aetje

Troubleshooting met HAMERRR

Dan heb je in de 1e prog je database niet gesloten na de transactie. Gooi er een IBDatabase1.Close; bij op de juiste plek (einde transactie).

Forget your fears...
...and want to know more...


  • marenk_vos
  • Registratie: Augustus 2001
  • Laatst online: 23-07 13:21
whoami ik zie dat je db.startransaction gebruikt maar bij interbase is het toch de transaction waartegen je moet zeggen starttransaction?

Als ik mijn database close dan moet ik hem daarna weer meteen openen? anders heb ik niks meer in mijn dbgrid staan.......

Dell XPS 17 Intel i7 2630 Nvidia GT555 3Gb Hd1: OCZ Vertex 2 SSD 60 GB Hd2: 500Gb


  • whoami
  • Registratie: December 2000
  • Laatst online: 20:46
marenk_vos schreef op 20 November 2002 @ 10:54:
whoami ik zie dat je db.startransaction gebruikt maar bij interbase is het toch de transaction waartegen je moet zeggen starttransaction?
Ja, mijn voorbeeld was enkel ter illustratie. :+
Ik ben gewend van de TDatabase, TQuery, ... componenten te gebruiken vandaar.
Maar met Interbase componenten is het principe hetzelfde.
Het openhoudne van een transactie moet zo kort mogelijk zijn.
Als ik mijn database close dan moet ik hem daarna weer meteen openen? anders heb ik niks meer in mijn dbgrid staan.......

Waarom zou je je database closen?
Als je je database closed, dan sluit je de connectie naar de databank en kan de applicatie geen gegevens meer uit de db halen.
Als je dan de database weer opent, dan moet de connectie enzo weer opgebouwd worden, wat een zeer 'dure' taak is. Je kunt beter je Query refreshen of je query sluiten/openen.

https://fgheysels.github.io/


  • marenk_vos
  • Registratie: Augustus 2001
  • Laatst online: 23-07 13:21
ok, ik voel me op het moment echt even een noob maareh het werkt nog steeds niet goed.

Als ik puur alleen naar de code kijk lijkt onderstaande code mij heel erg logisch en correct... toch werkt het niet:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure TForm2.FormShow(Sender: TObject);
begin
Form1.IBTable1.Open;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.IBTransaction1.StartTransaction;
Form1.IBTable1.edit;
Form1.IBTable1PROJECTNR.value:=edit1.text;
Form1.IBTable1.Post;
Form1.IBDatabase1.ApplyUpdates([form1.ibtable1]);
Form1.IBTransaction1.Commit;
Form1.IBTable1.Open;
end;


Ik krijg bij het drukken op de button voor opslaan de foutmelding, transaction is active... en dat kan niet want in design heb ik alles uit staan en in form 1 gebeurd niets meer behalve de button om naar form2 toe te gaan

Dell XPS 17 Intel i7 2630 Nvidia GT555 3Gb Hd1: OCZ Vertex 2 SSD 60 GB Hd2: 500Gb


  • marenk_vos
  • Registratie: Augustus 2001
  • Laatst online: 23-07 13:21
Op de een of andere manier handel ik iets niet goed af.... als ik nameljk in de 2e applicatie de foutmelding krijg van de deadlock (die ik krijg als ik een gewijzigd record in de 1e applicatie in de 2e applicatie opnieuw wil wijzigen) dna zie ik de record inhoud zoals die moet zijn... dus zoals applicatie 1 hem gewijzigd heeft... als ik da de foutmelding wegklik zie ik weer de verouderde data... Ook al open ik in de 2e app de tabel opnieuw en refres ik hem.

Dell XPS 17 Intel i7 2630 Nvidia GT555 3Gb Hd1: OCZ Vertex 2 SSD 60 GB Hd2: 500Gb


  • whoami
  • Registratie: December 2000
  • Laatst online: 20:46
marenk_vos schreef op 20 november 2002 @ 11:19:
ok, ik voel me op het moment echt even een noob maareh het werkt nog steeds niet goed.

Als ik puur alleen naar de code kijk lijkt onderstaande code mij heel erg logisch en correct... toch werkt het niet:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure TForm2.FormShow(Sender: TObject);
begin
Form1.IBTable1.Open;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.IBTransaction1.StartTransaction;
Form1.IBTable1.edit;
Form1.IBTable1PROJECTNR.value:=edit1.text;
Form1.IBTable1.Post;
Form1.IBDatabase1.ApplyUpdates([form1.ibtable1]);
Form1.IBTransaction1.Commit;
Form1.IBTable1.Open;
end;


Ik krijg bij het drukken op de button voor opslaan de foutmelding, transaction is active... en dat kan niet want in design heb ik alles uit staan en in form 1 gebeurd niets meer behalve de button om naar form2 toe te gaan

Je opent je tabel, maar je sluit hem niet.
code:
1
2
3
IBTransaction1.Commit();
Tabel1.Close();
Tabel1.Open();

https://fgheysels.github.io/


  • marenk_vos
  • Registratie: Augustus 2001
  • Laatst online: 23-07 13:21
Geen verbetering..... en nog steeds deadlocks

Dell XPS 17 Intel i7 2630 Nvidia GT555 3Gb Hd1: OCZ Vertex 2 SSD 60 GB Hd2: 500Gb


  • whoami
  • Registratie: December 2000
  • Laatst online: 20:46
Wat doet die 2 applicatie precies en wat doet die 1ste app precies?

https://fgheysels.github.io/


  • marenk_vos
  • Registratie: Augustus 2001
  • Laatst online: 23-07 13:21
de laatste code die ik getypt heb dat is DE test applicatie, die wordt vlak na elkaar opgestart, in de ene applicatie maak ik de wijziging door op de button te drukken, vervolgens sluit ik het scherm en open ik het scherm in de 2e applicatie.

Er gebeuren dus 2 dingen: Formshow, waarbij de dbgrid wordt getoond en de buttonclick waarbij er een wijziging wordt aangebracht.

Dell XPS 17 Intel i7 2630 Nvidia GT555 3Gb Hd1: OCZ Vertex 2 SSD 60 GB Hd2: 500Gb


  • marenk_vos
  • Registratie: Augustus 2001
  • Laatst online: 23-07 13:21
Is er niemand die mij hiermee verder kan helpen?

Dell XPS 17 Intel i7 2630 Nvidia GT555 3Gb Hd1: OCZ Vertex 2 SSD 60 GB Hd2: 500Gb


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Hoe zijn je locking en cursor instellingen?

We adore chaos because we like to restore order - M.C. Escher


  • marenk_vos
  • Registratie: Augustus 2001
  • Laatst online: 23-07 13:21
Waar kan ik dat bekijken? In de interbase console kan ik die instellingen niet vinden.

Dell XPS 17 Intel i7 2630 Nvidia GT555 3Gb Hd1: OCZ Vertex 2 SSD 60 GB Hd2: 500Gb


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Bij de componenten, maar ik heb even gekeken en IB werkt toch iets anders dan wat ik gewend ben qua instellingen.

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Ik gebruik ook Interbase, Delphi en IBX componenten. Voor de locking instellingen moet je bij de property Params van het IBTransaction component kijken (of dubbel klikken op dit component).

Ik heb deze ingesteld als: isc_tpb_nowait.

  • marenk_vos
  • Registratie: Augustus 2001
  • Laatst online: 23-07 13:21
zijn de IBX componenten anders dan de standaard componenten die in delphi5 zitten? Ik weet dat er een IBX setup zit in de installatie map op de cdrom... Heb je die soms geinstallerd?

Dell XPS 17 Intel i7 2630 Nvidia GT555 3Gb Hd1: OCZ Vertex 2 SSD 60 GB Hd2: 500Gb


Verwijderd

De componenten die in delphi staan zijn de IBX componenten. Ik gebruik dan zelf Delphi 6/7.

  • marenk_vos
  • Registratie: Augustus 2001
  • Laatst online: 23-07 13:21
Misschien is het wel niet helemaal correct maar zou iemand eventueel een klein voorbeeldje kunnen mailen..... Ik krijg het namelijk niet goed..... Alleen basis is al ruim voldoende, een form met een dbrid die wat toevoegd lukt mijn in feite zelf ook maar wanneer er een 2e applicatie naast gestart wordt dan zie ik niet de gewijzigde gegevens in dat scherm....

Ik zou er enorm mee geholpen zijn. Delphi 5 ~ 7 maakt niet uit..

Dell XPS 17 Intel i7 2630 Nvidia GT555 3Gb Hd1: OCZ Vertex 2 SSD 60 GB Hd2: 500Gb


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

marenk_vos schreef op 22 November 2002 @ 12:40:
maar wanneer er een 2e applicatie naast gestart wordt dan zie ik niet de gewijzigde gegevens in dat scherm....
Dat is ook juist gedrag. Zonder opnieuw de recordset op te vragen komen er niet zomaar wijzigingen door van de andere kant. Het zou ook teveel netwerk en database verkeer kosten als dat wel zo was. Vaak wordt locaal in een soort cache de gegevens vastgehouden en pas geupdate als daar specifiek opdracht tot is gegeven. Ongeveer zoals het zou werken met een DB koppeling op een webpagina. Soms kan het zo ingesteld worden dat je wel alle wijzigingen automatisch doorkrijgt, maar of en hoe dat met IB kan kan ik je helaas niet vertellen.

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Even over dat opehouden van transacties.. hoewel het vanuit applicatie-oogpunt wel beter is, maakt het voor interbase niet zo gruwelijk veel uit. Een transactie HOEFT helemaal niet zo snel gesloten te worden, zo lang je 'm maar niet langer dan een dag openhoudt..

http://bdn.borland.com/ar...0,27569,00.html#Subtopic4
Quite often in the newsgroups you will hear comments to the effective don't hold transactions open for a long period of time. Is never qualified as to what a long period of time is. The duration of the transaction isn't necessarily as important as to what is done with the transaction. If you're going to hold a transaction open for a day and do nothing with it, that is not nearly as severe as holding transactions open all day and running a query against a every minute and a half. The former will prevent InterBase from doing garbage collection. The latter will also prevent InterBase from doing garbage collection and in addition will cause InterBase to consume more and more memory to keep track of what is going on in the transaction. The latter can cause significant slowdowns in performance. For example one company would open their application in the morning and InterBase would be consuming roughly 180 to 200 megs of memory on the server. Because transactions were being held open all day and select queries being run against them, by the end of the day, InterBase was consuming 950 megs of memory. The difference in performance was readily visible when the backups were run. With InterBase consuming 950 megs of memory the backup would take an hour to run. If you shut down InterBase and restarted it to free all the memory, the backup would take six minutes.

So, holding transactions open for several minutes isn't a major problem. Holding a transaction open all day and running lots of queries against that transaction can cause problems.
//edit

inhoudelijk:

probeer na het committen nog even een Commitupdates...

//edit scratch my last remark.. die kennen de IBX compo's niet.. momentje, ik ga even kijke of ik een werkend voorbeeldje kan bakken..

[ Voor 9% gewijzigd door Verwijderd op 22-11-2002 13:19 ]


  • ProgrammerX
  • Registratie: Juli 2002
  • Laatst online: 26-02-2021
Heb je als je gebruikt maakt van de ibx componenten ook niet properties zoals de sql sharemode van de bde (shared autocommit ,shared noautocommit en not shared) ?

Heb namelijk zelf ook al eens zitten kloten met precies dit probleem, alleen maakte we toen gebruik van de bde er tussen. Probeer anders eens met 2 sql explorer's van delphi zelf en laat die allebei connecten naar de database. Als je in explorer1 een record toevoegt en je drukt dan op de refresh van explorer2 zou je dit nieuwe record al moeten zien, althans dat was bij ons toen wel zo.

Wij zijn toen 'vastgelopen' met het transactie mechanisme van de ib server en stored procedures. Weet het niet meer precies maar i.c.m. stored procedures kregen we het toen niet aan de gang.

Succes ermee !! :)

Verwijderd

Voor zover ik kan vinden is de enige mogelijkheid het heropenen van de query in beide applicaties:

http://groups.google.com/...5c_2%2540dnews%26rnum%3D8

Eventueel zou je hiervoor de 'onidletimer' property kunnen gebruiken, verwacht echter een hoop verkeer hierdoor.

  • marenk_vos
  • Registratie: Augustus 2001
  • Laatst online: 23-07 13:21
Ik heb mijn simpele programmaatje werkend !!!!!!! HOERA.......

Bij deze zal ik even mijn ervaringen/frustraties melden zodat iemand die net als mij een klein progrje wil bouwen met interbase niet het wiel opnieuw hoeft uit te vinden.

1. Je hoeft de transactie in feite maar 1x te openen mits je overal in je code transaction.commitretained gebruikt.
2. De transactie opent automatisch als je van tevoren je IBTable.open (t) Het volgende commando geeft dus een error ibtable.open , transaction.starttransaction achter elkaar
3. Gebruik de trasactie mode: READ COMMITTED, (een dubbelklik op de transactie en dan de 2e radiobutton
4. voorbeeldje van een simple progje:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
procedure TForm2.FormShow(Sender: TObject);
begin
Form1.IBTable1.Open;
Form1.IBTable1.refresh;    // vergeet de refresh vooral niet !!!!!
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.IBTable1.edit;
Form1.IBTable1PROJECTNR.value:=edit1.text;
Form1.IBTable1.Post;
Form1.IBDatabase1.ApplyUpdates([form1.ibtable1]);
Form1.IBTransaction1.CommitRetaining;        
end;

[ Voor 4% gewijzigd door marenk_vos op 22-11-2002 14:50 . Reden: Refresh vergent.... ]

Dell XPS 17 Intel i7 2630 Nvidia GT555 3Gb Hd1: OCZ Vertex 2 SSD 60 GB Hd2: 500Gb

Pagina: 1