Toon posts:

[vb] Rollback transactie na een delete query

Pagina: 1
Acties:

Verwijderd

Topicstarter
Dit is mijn code

werkplek.BeginTrans
''Delete resultaten
errstring = "delete resultaten"
DoCmd.RunSQL "delete * from resultaat", -1
''Herindexeren van resultaat
errstring = "Herindexeren van resultaat tabel mislukt"
comm = Shell("C:\fbaserver\osql.exe etc
''QTM->Resultaat - Resultaat
errstring = "Importeren van dagelijkse resultaat tabel"
Set qd = db.QueryDefs("QTM->Resultaat - Resultaat")
qd.Execute
errstring = " Done"
werkplek.CommitTrans

Als er nu tijdens de transactie iets fout gaat dan voert hij de rollback uit. Dit werkt in alle gevalle behalve wanneer ik dus bovenstaande delete query doe. Nadat de transactie fout is gegaan is de tabel leeg, en dat moet dus niet. Als ik een insert query doe dan werkt het wel. Iemand enig idee hoe dit kan. Ohja, de -1 achter het RunSQL command betekend UseTransaction = Yes.

Verwijderd

Wat wil je in vredesnaam allemaal doen? waarom roep je osql.exe aan?

Aan het delete statement te zien werk je met Access. Het kan best zijn dat access geen transactions ondersteunt.

Het beste kun je een command maken met je query, via de BeginTrans method van het connection object een transaction starten, de execute method van je command object aanroepen en wanneer er geen errors plaatsvonden, de CommitTrans method aanroepen of indien wel een error, de RollbackTrans method.

Stukje code geknipt uit een tool die xml sets met calls importeert en de calls uitvoert op andere databases:
code:
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
On Error Goto Handler

    '...

    '---------------------
    ' Use ADO .begintrans .committrans and .rollbacktrans on the CONNECTION object
    '---------------------
    m_gacoConnection.IsolationLevel = adXactIsolated      ' most restricted level of transaction isolation
    ' Start a transaction
    m_gacoConnection.BeginTrans
      bTransactionStarted = True
      For Each xnSPCall In xnlSPCalls
        iSPCallsCntr = iSPCallsCntr + 1
        pbImportProgress.Value = iSPCallsCntr
        DoEvents
        ' Execute the call. This call will eventually add identitymappings.
        bResult = ExecuteLoggedSPCall(xnSPCall, coSyncerData)
        If Not bResult Then
            ' Failed.
            Err.Raise -1, , "Couldn't continue due to fatal error in ExecuteLoggedSPCall."
        End If
      Next
      ' all went well.
    ' Commit the started transaction
    m_gacoConnection.CommitTrans
    m_gacoConnection.IsolationLevel = adXactChaos

    '...

    exit function

Handler:
    ' rollback the transaction
    If bTransactionStarted Then
      m_gacoConnection.RollbackTrans
    End If
    ' reset isolation level to default
    m_gacoConnection.IsolationLevel = adXactChaos
   
    '...

  • whoami
  • Registratie: December 2000
  • Laatst online: 06:24
Op woensdag 16 januari 2002 10:32 schreef Otis het volgende:

Aan het delete statement te zien werk je met Access. Het kan best zijn dat access geen transactions ondersteunt.
Naar mijn ervaring wel. Ik ben hier bezig met een Delphi programma die connectie maakt met een Access DB. Ik maak ook gebruik van transacties en alles schijnt fijn te werken.

Wat die osql doet, dat snap ik ook ff niet.

lisson01: Je zegt dat die Rollback niet wordt uitgevoerd, maar ik zie ook nergens Rollback staan in uw code. Of heb ik niet goed gekeken?

https://fgheysels.github.io/


Verwijderd

Topicstarter
Met die osql functie roep ik de volgende regel aan

dbcc checkident(resultaat,RESEED,0)

Deze functie werkt namelijk alleen via OSQL als je gebruik maakt van de MSDE.

Verwijderd

Dat is een dba functie, die behoor je niet te gebruiken in productiecode. Ik weet waar je op doelt, maar dat gaat niet werken.

(overigens, het is DELETE FROM bla, niet DELETE * FROM bla, ook bij MSDE)

Wat je wilt is in een table met een ident column de initial startvalue voor het eerstvolgende record weer terugzetten naar de initiele waarde wanneer een transaction mislukt.

voorbeeld: je insert 20 rows, je identcolumn startvalue is na die actie 20 hoger. Je transaction rolt terug, die 20 rows zijn weg, maar je identcolumn seed BLIJFT 20 hoger. Die rolt niet terug naar de initiele value.

Dit is logisch: wanneer je 2 users hebt die allebei tegelijk rows inserten, en bij 1 gaat het mis en die rolt terug, KUN je de identcolum seed niet terugzetten naar de initiele value, want die andere user heeft keys geinsert die HOGER zijn dan de initiele seed VOOR de insertactie die niet slaagde (van die ene user), dus je krijgt in de toekomst hoe dan ook PK constraint voilations.

De snippet die ik postte komt uit een tool die ik heb moeten maken om dit probleem te ondervangen: 2 databases, de 1 developer de ander productie, waarbij de developer middels een tool acties uitvoert op de developer database. Die acties dacht ik slim te re-playen op de productie database, maar wanneer dat mis ging en ik de transactie terugrolde, bleven de identcolumns op de nieuwe waarden staan. Opnieuw de acties afspelen opde prod. database leverde nieuwe keys op die dus in tables waar ik foreignkey rows inserte niet voorkwamen, en het dus een janboel werd.

Ik heb code gemaakt die keymappings opslaat, zodat bij het afspelen van calls met keys, de nieuwe ident colum values worden 'aangepast' aan de situatie van de database, en dit gaat altijd goed.

Ik kan me niet echt een situatie bedenken waarbij je dit verder nog zou willen, buiten replicatie probs zoals ik had. Kun je wat meer uitleggen WAAROM je het zou willen, wellicht kunnen we het hier dan zo voor je oplossen omdat iemand het al eerder heeft moeten doormaken :)

Verwijderd

Topicstarter
Ik exporteer dagelijks mijn resultaten tabel naar een telemarketing bureau. Op het moment dat zij hem ontvangen dan is hun tabel leading, om het maar even zo te noemen. Zij mogen er alles mee doen wat ze willen. Als zij de volgende ochtend klaar zijn dan krijgen we de tabel terug. Deze moet dus de complete tabel die we al hadden replacen. Ik heb dat nu voorelkaar, de originele tabel wordt getruckt, waardoor de reseed ook automatisch op 0 komt. De DTS die de informatie copyeerd van de import tabel naar mijn database doet een identity insert, dus de keys blijven het zelfde(is niet eens zo belangrijk wil gewoon niet dat er na 2 weken een record in zit met het nummer 1000000,)

Verwijderd

Als je als identtype 'yes (not for replication)' kiest, zou de DTS de keys moeten inserten die hij krijgt uit de file, niet nieuwe keys. Maar de trunk actie werkt idd ook
Pagina: 1