Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Rollback nach Select zerstört Transaktion

  1. #1
    JSpatz ist offline Benutzer
    Registriert seit
    19.05.2006
    Beiträge
    58

    Standard Rollback nach Select zerstört Transaktion

    HI zusammen,

    ich habe ein großes Problem mit dem ODBC Treiber von PostgreSQL, aber erst mal eine Kurze Beschreibung worum es geht:

    Ich portiere zur Zeit eine Anwendung, die mit Gupta-SQL-Windows programmiert ist (4GL Sprache vergleichbar mit Delphi), WindowsXP von der eigenen Gupta-SQL-Base auf PostgreSQL 8.2.
    Auf die Datenbank greife ich über ODBC zu (Version 8.02.02.00 Unicode, Datenbank ist UTF8 codiert). So weit so gut.
    Da ich ziemlich umfangreiche Transaktionen habe, arbeite ich (natürlich) ohne Autocommit und bin dabei auf folgendes Verhalten gestoßen:

    Zum Beispiel werden Datensätze in eine Tabelle eingefügt und dann wieder ausgelesen. Da alles innerhalb einer Transaktion läuft sollte man meinen, dass man die Datensätze sieht, die da eben eingefügt wurden.

    Der Code mit dem das passiert könnte so aussehen:


    Set sUser = 'SYSADM'
    Set sWS = 'WS_JSP'
    !
    Set sInfo = 'Test1'
    Set nError = nError and SqlPrepareAndExecute( hSql, 'insert into sysadm.log (dbuser, ws, info) Values ( :sUser, :sWS, :sInfo ) ' )
    !
    Set sInfo = 'Test2'
    Call SqlPrepareAndExecute( hSql, 'insert into sysadm.log (dbuser, ws, info) Values ( :sUser, :sWS, :sInfo ) ' )
    !
    Set sInfo = 'Test3'
    Call SqlPrepareAndExecute( hSql, 'insert into sysadm.log (dbuser, ws, info) Values ( :sUser, :sWS, :sInfo ) ' )
    !
    Set sInfo = ''
    !
    Call SqlPrepareAndExecute( hSql, 'Select info from sysadm.log into :sInfo' )
    Call SqlFetchNext( hSql, nError )
    Call SQLCommit(hSql)

    sUser, sWS und sInfo sind lokale String Variablen, hSql ist ein SQL-Handle oder eine Connection
    (Es handelt sich hier natürlich nicht um den echten Code, sondern nur um ein Beispiel, das ganze Fehlerhandling fehlt hier)

    Wenn ich vor dem Select ein Commit mache geht alles wunderbar. Wenn ich den Commit dort mache, wo er jetzt steht wird nichts selektiert und die Datensätze kommen auch nicht in der Tabelle an.

    Wenn man sich jetzt das Logfile des ODBC-Treibers ansieht erkennt man auch sofort warum:


    conn=01ED9A78, PGAPI_DriverConnect( in)='DSN=ALSAPLOG;UID=sysadm;PWD=xxxxxxxx;DATABASE =alsaplog;SERVER=localhost;PORT=5432;CA=d;A6=;A7=1 00;A8=4096;B0=254;B1=32000;BI=0;C2=dd_;CX=1bd27bb; A1=7.4-1;', fDriverCompletion=0
    DSN info: DSN='ALSAPLOG',server='localhost',port='5432',dbas e='alsaplog',user='sysadm',passwd='xxxxx'
    onlyread='0',protocol='7.4',showoid='0',fakeoidind ex='0',showsystable='0'
    conn_settings='',conn_encoding='OTHER'
    translation_dll='',translation_option=''
    Global Options: Version='08.02.0200', fetch=100, socket=4096, unknown_sizes=0, max_varchar_size=254, max_longvarchar_size=32000
    disable_optimizer=1, ksqo=1, unique_index=1, use_declarefetch=0
    text_as_longvarchar=1, unknowns_as_longvarchar=0, bools_as_char=1 NAMEDATALEN=64
    extra_systable_prefixes='dd_', conn_settings='' conn_encoding='OTHER'
    [ PostgreSQL version string = '8.2.1' ]
    [ PostgreSQL version number = '8.2' ]
    conn=01ED9A78, query='select oid, typbasetype from pg_type where typname = 'lo''
    [ fetched 0 rows ]
    [ Large Object oid = -999 ]
    [ Client encoding = 'UTF8' (code = 6) ]
    conn=01ED9A78, PGAPI_DriverConnect(out)='(NULL)'
    CONN ERROR: func=SQLDriverConnectW, desc='', errnum=215, errmsg='the ConnStrOut is too small'
    ------------------------------------------------------------
    henv=01ED3E10, conn=01ED9A78, status=1, num_stmts=16
    sock=01EDE8B0, stmts=01ED8C80, lobj_type=-999
    ---------------- Socket Info -------------------------------
    socket=1536, reverse=0, errornumber=0, errormsg='(NULL)'
    buffer_in=32359872, buffer_out=32370328
    buffer_filled_in=77, buffer_filled_out=0, buffer_read_in=77
    conn=01ED9A78, query='show max_identifier_length'
    [ fetched 1 rows ]
    conn=01ED9A78, query='insert into sysadm.log (dbuser, ws, info) Values ( E'SYSADM' , E'WS_JSP' , E'Test1' ) '
    conn=01ED9A78, query='insert into sysadm.log (dbuser, ws, info) Values ( E'SYSADM' , E'WS_JSP' , E'Test2' ) '
    conn=01ED9A78, query='insert into sysadm.log (dbuser, ws, info) Values ( E'SYSADM' , E'WS_JSP' , E'Test3' ) '
    conn=01ED9A78, query='Select info from sysadm.log '
    [ fetched 3 rows ]
    conn=01ED9A78, query='select n.nspname, c.relname, a.attname, a.atttypid, t.typname, a.attnum, a.attlen, a.atttypmod, a.attnotnull, c.relhasrules, c.relkind, c.oid, d.adsrc from (((pg_catalog.pg_class c inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace and c.oid = 54883) inner join pg_catalog.pg_attribute a on (not a.attisdropped) and a.attnum > 0 and a.attrelid = c.oid) inner join pg_catalog.pg_type t on t.oid = a.atttypid) left outer join pg_attrdef d on a.atthasdef and d.adrelid = a.attrelid and d.adnum = a.attnum order by n.nspname, c.relname, attnum'
    [ fetched 12 rows ]
    PGAPI_Columns: table='log',field_name='zeit',type=1114,name='time stamp'
    PGAPI_Columns: table='log',field_name='dbuser',type=1043,name='va rchar'
    PGAPI_Columns: table='log',field_name='ws',type=1043,name='varcha r'
    PGAPI_Columns: table='log',field_name='modul',type=1043,name='var char'
    PGAPI_Columns: table='log',field_name='info',type=1043,name='varc har'
    PGAPI_Columns: table='log',field_name='fenster',type=1043,name='v archar'
    PGAPI_Columns: table='log',field_name='salcomtype',type=1043,name ='varchar'
    PGAPI_Columns: table='log',field_name='iserror',type=21,name='int 2'
    PGAPI_Columns: table='log',field_name='errnumber',type=23,name='i nt4'
    PGAPI_Columns: table='log',field_name='statement',type=25,name='t ext'
    PGAPI_Columns: table='log',field_name='comtyp',type=1043,name='va rchar'
    PGAPI_Columns: table='log',field_name='dbtable',type=1043,name='v archar'
    conn=01ED9A78, query='ROLLBACK'
    conn=01ED9A78, query='Select info from sysadm.log '
    [ fetched 0 rows ]
    conn=01ED9A78, query='COMMIT'
    conn=01ED9A78, PGAPI_Disconnect

    Hier sieht man in der unteren Hälfte sehr deutlich die Inserts und dann den Select. Dann folgen Befehle, mit denen das Laufzeitsystem ermittelt, welche Spalten die Tabelle hat, auf der der Select läuft, und dann ein ROLLBACK. Mitten in der Transaktion. Und dann sind die eingefügten Zeilen natürlich wieder weg.

    Der erste Select ist also nur ein Dummy-Select, um die Struktur des Ergebnisses zu erfahren, dann kommt der Rollback und dann erfolgt der eigentliche Select, um die Daten zu holen, die dann natürlich weg sind.
    In der Log-Datei, die die Gupta schreibt fehlt dieses Rollback und auch mit SQL-Server ODBC funktioniert es einwandfrei. Deswegen habe ich den PG-ODBC Treiber in Verdacht. Habe ich hier evtl nur die falschen Einstellungen ? oder hat da sonst jemand eine Idee was ich falsch mache.

    Aber grundsätzlich muss es doch möglich sein innerhalb einer Transaktion Daten zu schreiben und dann evtl. auch ganz andere zu lesen. Das kann doch nicht sein, dass da noch ein Fehler an dieser Stelle im Treiber ist.

    Der ODBC Treiber ist mit folgenden Einstellungen installiert.

    Datasource/Page1
    Disable Genetic Optimizer = ON
    KSQO = ON
    Recognize Unique Indexes = ON
    Use Declare/Fetch = OFF
    CommLog = ON (zum testen, sonst OFF)
    Parse Statements = OFF
    Cancel as FreeStmt = OFF (testweise ON, bringt aber auch nichts)
    MyLog = OFF
    Unknown Size = Maximum
    Data Type Options
    Test as LongVarChar = ON
    Unknowns as LongVarChar = OFF
    Bools as Char = ON
    Miscellaneous
    Max Varchar = 254
    Max Long Varchar = 32000
    Chache Size = 100
    Sys Table Prefix = dd_:

    Datasource/Page2
    Read Only = OFF
    Show System Table = OFF
    LF <-> CR/LF conversion = ON
    Updateable Cursors = ON
    bytea as LO = OFF
    Row Versioning = ON
    Disallow Premature = OFF
    True is -1 = OFF
    Server side prepare = OFF
    INT9 as = Default
    Protokoll = 7.4+
    Level of rollback on errors = Transaction
    OID Opitions = OFF

    Treiber PostgreSQL Unicode

    Für Hilfe wäre ich sehr dankbar, sonst kann ich das Projekt abschreiben.

    JSP
    Geändert von JSpatz (04.03.2007 um 17:57 Uhr)

  2. #2
    JSpatz ist offline Benutzer
    Registriert seit
    19.05.2006
    Beiträge
    58

    Standard Fehler gefunden

    Hi zusammen,

    ich denke ich habe meinen Fehler gefunden:

    Im ODBC-Treiber muss die Einstellung Parse Statement = ON gesetzt werden und dann funktioniert das ganze.
    Ich bin mir aber jetzt immer noch nicht sicher, wo der Fehler herkam, denn mit perl tritt er nicht auf.

    Auf jeden Fall wird das Rollback dann nicht gemacht.

    Danke trotzdem

  3. #3
    akretschmer ist gerade online Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.467

    Standard

    Zitat Zitat von JSpatz Beitrag anzeigen
    Hi zusammen,

    ich denke ich habe meinen Fehler gefunden:

    Im ODBC-Treiber muss die Einstellung Parse Statement = ON gesetzt werden und dann funktioniert das ganze.
    Danke für die Rückinfo, finde ich nett für alle, die drüber nachgedacht haben.

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  4. #4
    ipConfig ist offline Erfahrener Benutzer
    Registriert seit
    21.02.2007
    Ort
    56072 Koblenz
    Beiträge
    125

    Ausrufezeichen doch nicht gelöst

    Hallo, leider ist das Problem doch noch nicht gelöst...

    Hier ist ein Auszug aus psqlodbc_****.log:

    Code:
    conn=01FE0E70, query='INSERT INTO T_AKTION   (ROWVERSION, NAKTIONKEY, AENDERUNGSDATUM, BEARBEITER, DTDATUMBIS, DTDATUMVON, ERFASSER, ERFASSUNGSDATUM, NMANDANTKEY, SBEZEICHNUNG)   VALUES (1,'68'::float8, '2007-03-06 09:58:08'::timestamp, E'IP', '2007-03-16 00:00:00'::timestamp, '2007-03-06 00:00:00'::timestamp, E'IP'             ,'2007-03-06 09:58:08'::timestamp, '1'::float8, E'06.03-16.03-104-IP'                 )'
    conn=01FE0E70, query='SELECT IntToChar( ROWVERSION) from T_AKTION WHERE NAKTIONKEY=NULL               '
        [ fetched 0 rows ]
    conn=01FE0E70, query='ROLLBACK'
    conn=01FE0E70, query='SELECT IntToChar( ROWVERSION) from T_AKTION WHERE NAKTIONKEY='68'::float8               '
        [ fetched 0 rows ]
    conn=01FE0E70, query='  UPDATE T_Lookuptable SET Aenderungsdatum  = '2007-03-06 09:58:08'::timestamp WHERE LutID = '4'::float8 and nMandantKey = '1'::float8'
    conn=01FE0E70, query='COMMIT'
    Der ODBC-Treiber verursacht folgende Befehle:
    Code:
    conn=01FE0E70, query='SELECT IntToChar( ROWVERSION)  from T_AKTION WHERE NAKTIONKEY=NULL '
        [ fetched 0 rows ]
    conn=01FE0E70, query='ROLLBACK'
    Wie kann ich ihm das abgewöhnen????
    Wo gibt es ein genaue Dokumentation des ODBC-Treibers?

    Ich kann dem ODBC-Treiber "Connect-Settings" mitgeben, welche wären das?

    Brauche dringend Hilfe, da am Montag eine Pilotierung bevorsteht.

    alle Einstellungen sind wie von JSpatz beschrieben...

    MFG
    Ingo

  5. #5
    akretschmer ist gerade online Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.467

    Standard

    Zitat Zitat von ipConfig Beitrag anzeigen

    Der ODBC-Treiber verursacht folgende Befehle:
    [CODE]conn=01FE0E70, query='SELECT IntToChar( ROWVERSION) from T_AKTION WHERE NAKTIONKEY=NULL '


    MFG
    Ingo

    Ein Vergleich a la 'FOO=NULL' wird nicht funktionieren, dazu gibt es where foo is null'. Ich weiß nicht, ob Du oder der ODBC-Treiber diesen Unfug macht...


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  6. #6
    ipConfig ist offline Erfahrener Benutzer
    Registriert seit
    21.02.2007
    Ort
    56072 Koblenz
    Beiträge
    125

    Standard

    Hallo,

    Danke für die schnelle Antwort!

    Das kommt definitiv nicht von mir...
    Meine beiden Statements sind die folgenden:

    Code:
    INSERT INTO T_AKTION   (ROWVERSION, NAKTIONKEY, AENDERUNGSDATUM, BEARBEITER, DTDATUMBIS, DTDATUMVON, ERFASSER, ERFASSUNGSDATUM, NMANDANTKEY, SBEZEICHNUNG)   VALUES (1,'68'::float8, '2007-03-06 09:58:08'::timestamp, E'IP', '2007-03-16 00:00:00'::timestamp, '2007-03-06 00:00:00'::timestamp, E'IP', '2007-03-06 09:58:08'::timestamp, '1'::float8, E'06.03-16.03-104-IP')'
    und

    Code:
    'SELECT IntToChar( ROWVERSION) from T_AKTION WHERE NAKTIONKEY='68'::float8'
    Die beiden anderen Statements kommen irgendwo anders her...
    und da habe ich den ODBC-Treiber im Verdacht...

    Abgesehen davon funktionieren aber beide Ausdrücke die du erwähnt hast (= NULL) und (IS NULL)
    Geändert von ipConfig (06.03.2007 um 11:17 Uhr)

  7. #7
    akretschmer ist gerade online Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.467

    Standard

    Zitat Zitat von ipConfig Beitrag anzeigen
    Hallo,

    Danke für die schnelle Antwort!

    Die beiden anderen Statements kommen irgendwo anders her...
    und da habe ich den ODBC-Treiber im Verdacht...
    Kipp einen Bugreport bei den ODBC-Leuten rein, das ist ein Bug, wenn es nicht von Dir kommt. Vielleicht kannst Du irgendwas mit Pass-trough machen, um den Treiber davon abzuhalten. Jedenfalls dürfte ein Vergleich der Form '= NULL' einen Fehler und damit ein Rollback auslösen.

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  8. #8
    ipConfig ist offline Erfahrener Benutzer
    Registriert seit
    21.02.2007
    Ort
    56072 Koblenz
    Beiträge
    125

    Standard Hurra

    folgender Eintrag im ODBC-Treiber hilft weiter:

    Disallow Premature = 1

    Damit wird dann der ODBC-Treiber anscheinen dazu gezwungen für "seine" Statements einen eigenen Cursor zu verwenden, sodass der Rollback sich dann auf sein "Reich" beschränkt ohne meine laufende Session zu stören....

    Trotzdem vielen Dank...

    PS:
    Großen Dank an JSpatz für die Lösung des Problems.

    PPS:
    Wo kann ich den Bugreport genau einreichen?

  9. #9
    akretschmer ist gerade online Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.467

    Standard


    Abgesehen davon funktionieren aber beide Ausdrücke die du erwähnt hast (= NULL) und (IS NULL)
    Mmh, stimmt. Sauber aber nicht:

    Code:
    test=*# select * from tab;
     t | t2
    ---+----
     x | y
     x |
    (2 rows)
    
    test=*# select * from tab where t2=null;
     t | t2
    ---+----
    (0 rows)
    
    test=*# select * from tab where t2 is null;
     t | t2
    ---+----
     x |
    (1 row)


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  10. #10
    ipConfig ist offline Erfahrener Benutzer
    Registriert seit
    21.02.2007
    Ort
    56072 Koblenz
    Beiträge
    125

    Standard

    Na wie du siehst ist dann der Ausdruck "= NULL" doch genau richtig... schliesslich geht es dem ODBC-Treiber darum die Tabellenstruktur rauszufinden. Und da muss dann sichergestellt sein das gar nichts zurückkommt... er braucht ja nur die spalten...

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Select nach Zahlen
    Von burkhard im Forum Allgemeines
    Antworten: 13
    Letzter Beitrag: 11.01.2010, 21:33
  2. Rollback mit Extra Anweisung
    Von CvonS im Forum Andere Datenbanken
    Antworten: 1
    Letzter Beitrag: 01.07.2009, 15:00
  3. Frage unterschiedliche ergebnisse nach wiederholtem select * ..
    Von symbiont im Forum Allgemeines
    Antworten: 3
    Letzter Beitrag: 10.08.2008, 21:43
  4. Select Nextval in Transaktion
    Von byte im Forum SQL
    Antworten: 3
    Letzter Beitrag: 10.04.2007, 07:40
  5. Rollback bei Fehler in Transaktion
    Von mwbond im Forum Programmierung
    Antworten: 10
    Letzter Beitrag: 04.01.2006, 16:30

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Links: Tobias Bauer - IT- und Funkdienstleistungen   -   Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen   -   Funkforum