Toon posts:

[Interbase, Delphi] Gegevens uit een andere transactie lezen

Pagina: 1
Acties:

Verwijderd

Topicstarter
Stel ik heb 1 schrijf query waaraan een transactie hangt (Ik noem deze ff Transactie A)

Hiermee laat ik data inserten.

Vervolgens heb ik een andere query waaraan een transactie gekoppeld zit (Ik noem deze ff Transactie B ). Nu wil ik dat het mogelijk is om in Transactie B gegevens te lezen die net in transactie A ingevoerd zijn maar nog NIET gecommit zijn.

Is dit mogelijk?

(Ik maak gebruik van de IBX componenten)

  • whoami
  • Registratie: December 2000
  • Laatst online: 17:24
Neen, dat is niet mogelijk.

https://fgheysels.github.io/


  • jvdmeer
  • Registratie: April 2000
  • Laatst online: 14:45
Wat jij wilt haalt het hele idee van transactions onderuit. Je kan eventueel wel Transaction B als sub-transactie van A behandelen.

Dus praktisch:
code:
1
2
3
4
5
6
7
Start Transactie A
  Doe wat
  Start Transactie B
  Doe meer
  Eindig Tranactie B
  Doe meer
Eindig Tranactie A

  • whoami
  • Registratie: December 2000
  • Laatst online: 17:24
jvdmeer schreef op 19 December 2002 @ 17:49:
Wat jij wilt haalt het hele idee van transactions onderuit. Je kan eventueel wel Transaction B als sub-transactie van A behandelen.

Dus praktisch:
code:
1
2
3
4
5
6
7
Start Transactie A
  Doe wat
  Start Transactie B
  Doe meer
  Eindig Tranactie B
  Doe meer
Eindig Tranactie A


Ben je dat zeker?
Ik denk niet dat dat mogelijk is, meestal kan je geen transactie starten als er reeds een transactie lopende is.

In .NET bv, is een transactie aan een connectie gekoppeld, en kan je slechts 1 lopende transactie hebben binnen die connectie.

In Delphi kan dat trouwens ook niet: 'A transaction is already in progress' krijg je als je volgende code gebruikt:
code:
1
2
DataModule1.Database1.StartTransaction();
DataModule1.Database1.StartTransaction();

[ Voor 15% gewijzigd door whoami op 19-12-2002 18:51 ]

https://fgheysels.github.io/


Verwijderd

Topicstarter
Ik zal trouwens nog ff uitleggen waarom ik het zo wilde gaan gebruiken.

We zijn met school bezig met een project Data Warehouse. Bij dit project hebben we een aantal winkels met hun eigen database's (allemaal SQL Server 2000) en een DWH (bij ons is dit Interbase 6).

Nu moeten wij een ETL applicatie bouwen, dus een programma die alle gegevens gaat synchroniseren op bepaalde tijden en een analyse applicatie voor het management.

Nu hebben uitgedacht om de ETL app als volgt te maken:

Voordat we alle nieuwe gegevens gaan opvragen bij een winkel starten we een transactie op de Interbase database.

Vervolgens gaan we dus alle gegevens synchroniseren (verkopen, producten, merken, klanten, enz....) Als er nu wat misgaat tijdens deze synchronisatie fasen dan rollbacken we alles terug. En uiteraard wordt aan het einde als alles goed gegaan is, alles gecommit.

Wij hebben nu 1 Query (A) met daaraan een transactie gekoppeld. Deze gebruiken we om te schrijven. (Dus bij deze starten we een transactie als het proces gaat beginnen)

Vervolgens hebben we een andere Query ( B ) met daaraan een transactie gekoppeld.

Allereerst gaan we de verkopen synchroniseren. Hier gebruiken we query A voor. (Ze worden dus niet gecommit!!).

Vervolgens gaan we bij stap 2 de producten synchroniseren. Dus we kijken in onze DWH of er nieuwe producten staan in de FACT tabel. (Dit doen we door een select query met een sub query uit te voeren op de FACT tabel en de PRODUCTEN tabel. We gebruiken hier query B voor).

Maar omdat de gegevens van transactie A niet toegankelijk zijn voor B en er dus niet gecommit kan worden, zullen er dus geen nieuwe producten zijn, omdat transactie B dat niet kan zien.

Waarom gebruik we een extra query om die nieuwe producten te vinden?
Dit doen we omdat we vervolgens in een keer die query B kunnen doorlopen (while do....). We krijgen tenslotte alle id's terug van de nieuwe producten en vervolgens kunnen we steeds direct transactie A gebruiken om deze gegevens op te slaan in onze DWH (dus de nieuwe product gegevens).


Nu weet ik wel een oplossing hiervoor. Namelijk gewoon de query die aan transactie A gekoppeld zit gebruiken. Alleen dan moet ik dat doen netzo lang totdat die select query met sub query geen rows meer terug geeft. Dus ik moet iedere keer weer opnieuw die select query met die sub query uitvoeren. Echter ik denk dat dit voor de perfomance niet echt goed is.

Maar is er misschien een andere oplossing. Maken wij een denk fout ?

  • whoami
  • Registratie: December 2000
  • Laatst online: 17:24
wijzigingen binnen niet gecommitte transacties kun je dus niet zien vanuit andere sessies.

Wat doet die query B trouwens?
Verder begrijp ik je uitleg niet zo goed, 't is een beetje vaag....

Maar goed, je kunt toch :
code:
1
2
3
4
Starttransactie
Lees();
write();
Commit

doen? Waarom ga je iedere query binnen een andere transactie uitvoeren?

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op 19 December 2002 @ 22:03:Wat doet die query B trouwens?
Query B is ervoor om steeds het id te bepalen van producten/merken/categorieen/enz... waarvan alle gegevens nog niet aanwezig zijn in de dwh.
Verder begrijp ik je uitleg niet zo goed, 't is een beetje vaag....
Oh...ik had gehoopt dat het zo wel duidelijk was.

Maar nog een poging:


==> Starttransactie A

==> Synchroniseer verkopen

==> De nieuwe verkoop gegevens zijn dus d.m.v. Query A geinsert in de DWH

==> Fase 2: Product synchronisatie

code:
1
2
3
4
5
SELECT PRODUCTID
FROM    FACT
WHERE PRODUCTID NOT IN
   (SELECT PRODUCTID 
    FROM    PRODUCT);


Deze query voer ik dus uit met query B.

Delphi:
1
2
3
4
5
6
7
8
9
10
  while not QueryB.EOF do
  begin
    // Gebruik nu de id's uit query B om hiermee alle product gegevens op te 
    // vragen bij de winkel door middel van een ado connection naar sql server
    
    // Vervolgens worden deze gegevens geinsert met behulp van query A.

    QueryB.Next;

  end;


Nu kan ik wel wat ik net zei alles doen met behulp van Query A. Maar dan zal ik dus iedere keer die select query + sub query opnieuw moeten uitvoeren i.p.v. met een lusje door die query lopen (eenmalig opvragen).

Ik denk dat het kwa performance beter is hoe ik het nu doe.

Maar goed als het niet anders kan moet het maar.

Heb ik het nu goed uitgelegd ? :)

Verwijderd

Waarom laat je die query B niet gewoon van dezelfde transactie gebruik maken? waarom moet die perse een eigen transactie hebben?

Verwijderd

Topicstarter
Verwijderd schreef op 19 december 2002 @ 23:28:
Waarom laat je die query B niet gewoon van dezelfde transactie gebruik maken? waarom moet die perse een eigen transactie hebben?
Dat werkt niet, dat heb ik namelijk al geprobeerd.

Verwijderd

Dan heb je het verkeerd geprobeerd, of ik begrijp niet wat je wilt. Even een voorbeeld, een ib database. Daar koppel ik een IBDatabase aan, 1 IB transactie en 2 IBQueries.

Als ik nu in query1 iets verander, dan zie ik die verandering gelijk in query2.

Dit geldt overigens zowel voor de Interbase componenten als de BDE componenten.

[ Voor 5% gewijzigd door Verwijderd op 19-12-2002 23:49 ]


  • jochemd
  • Registratie: November 2000
  • Laatst online: 25-08 15:35
Verwijderd schreef op 19 December 2002 @ 12:12:

Vervolgens heb ik een andere query waaraan een transactie gekoppeld zit (Ik noem deze ff Transactie B ). Nu wil ik dat het mogelijk is om in Transactie B gegevens te lezen die net in transactie A ingevoerd zijn maar nog NIET gecommit zijn.
Zoek even in de handleiding of een transaction isolation level READ_UNCOMMITED wordt ondersteund. Zo ja, opgelost, zo nee, onmogelijk.
Pagina: 1