AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Lockmode bei Updates
Thema durchsuchen
Ansicht
Themen-Optionen

Lockmode bei Updates

Ein Thema von Wegalt · begonnen am 3. Mär 2004 · letzter Beitrag vom 4. Mär 2004
Antwort Antwort
Wegalt

Registriert seit: 14. Nov 2003
12 Beiträge
 
#1

Lockmode bei Updates

  Alt 3. Mär 2004, 13:45
Hallo,

ich möchte ein Update absetzen, ohne das der Datensatz der upgedatet wird gespert wird.

Im Moment sieht das so aus!
SQL-Code:
        Table.Lockmode := lmNone;
        Table.KeyFields := 'SOURCEID';
        Table.FilterSQL := 'Filename = ''' + PDSFName + '''';
        Table.Open;
        Table.Edit;
        Table.FieldByName('EQUIPMENTID').AsString := EquipmentID;
        Table.POST;
Wenn die Verbindung jetzt vor dem Commit abreißt und ich dann das gleiche Update mit einer neuen Session absetzte, muß ich warten, bis die alte Session gekillt wurde.
Obwohl ich Lockmode := lmNone gesetzt habe.

Ich nutze
Oracle8i Enterprise Edition Release 8.1.6.0.0
und Odac 4.5

Ich hoffe ihr könnt mir helfen

Gruß
Wegalt
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#2

Re: Lockmode bei Updates

  Alt 3. Mär 2004, 17:19
Du kannst doch mit den ODAC-Kompos auch anonyme Blöcke absetzen, oder?
Ich habe mir die ODAC noch nicht angeschaut (sollen ja ganz gut sein...), so würde es mit Direct Oracle Access aussehen:

Dadurch schickst du alles in einem Stück an den Server. Transaktions- & Fehlerhandling wird er dann übernehmen.
Bei einem Fehler gibt es ein Rollback, die Fehlermeldung steht dann in ErrorStr.

Delphi-Quellcode:
Var
  ErrorStr : String;
Begin
  With OracleQuery Do
  Begin
    SQL.Text :=
      'Begin' + #10 +
      ' Update DeineTabelle' + #10 +
      ' Set EquipmentID = :i_EquipID' + #10 +
      ' WHERE FileName = :i_FileName;' + #10 +
      '' + #10 +
      ' Commit;' + #10 +
      'Exception' + #10 +
      ' When Others Then' + #10 +
      ' Rollback;' + #10 +
      ' :o_Errors := Sqlerrm;' + #10 +
      'End;';
    If Variables.Count = 0 Then
    Begin
      DeclareVariable('i_EquipID', otInteger);
      DeclareVariable('i_FileName', otString);
      DeclareVariable('o_Errors', otString);
    End;

    SetVariable('i_FileName', PDSFName);
    SetVariable('i_EquipID', EquipmentID);
    Execute;

    ErrorStr := GetVAriable('o_Errors');
  End;
  MessageDlg(ErrorStr, mtError, [mbOK], 0);

End;
  Mit Zitat antworten Zitat
Wegalt

Registriert seit: 14. Nov 2003
12 Beiträge
 
#3

Re: Lockmode bei Updates

  Alt 3. Mär 2004, 19:07
Also erstmal danke für deinen Vorschlag, da ich aber in mehere Tabelle etwas einzutragen oder zu updaten habe ist das leider nicht ganz meine Lösung. Commit will ich nur absetzen wenn alles geklappt hat(einige Exceptions wären sogar erlaubt)

Damit will ich mir das Löschen sparen wenn etwas nicht so ganz passt.


Ich habe mich mal schlau gemach und soetwas wie dieses..

SQL-Code:
UPDATE Users WITH (NOLOCK)
SET Username = 'fredWHERE Username = 'foobar'
..kann ich leider nicht benutzen. Oracle speert die Datensätze automatisch. Weiß nicht wo das geht?!

Irgendwie soll das mit DBMS_PIPE gehen. Sich mit der neuen Session (nach Verbindungsabbruch)
mit DBMS_PIPE auf die alte Session connecten und diese schließen.

Leider kann ich auch dieses..
Delphi-Quellcode:
   
OraSQL1.SQL.Text := 'alter system kill session ''' + slSidSerial[i] + '''';
OraSQL1.Execute;
..nicht nutzen, da ich keine Systemrechte habe.


Also wenn dir(euch) doch noch was einfällt?!

Gruß
Wegalt
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#4

Re: Lockmode bei Updates

  Alt 3. Mär 2004, 19:43
kill session ist keine gute Idee. Es kann vorkammen, dass eine session im Status "marked for kill" mehrere Stunden verbleibt (vor allem bei der 8.16).
Du kannst alle deine Updates in einen Block packen. Die effektive Zeit, die die Aktionen dann benötigen wird < 0,Irgendwas Sek. betragen.
In dieser Zeit kann die Tabelle für Schreibrechte doch gesperrt sein.
Gebe mir mal ein Beispiel, vielleicht kommen wir dann zu einer Lösung.
  Mit Zitat antworten Zitat
Wegalt

Registriert seit: 14. Nov 2003
12 Beiträge
 
#5

Re: Lockmode bei Updates

  Alt 4. Mär 2004, 14:13
Das es nicht so klasse ist die session zu killen hab ich schon gemerkt. Nach einer gewissen Zeit konnte sich keiner mehr an die DB anmelden weil zu viele Prozesse liefen. Es dauerte die ganze Nacht bis man die DB wieder vernünftig benutzen konnte.

Ich denke du hast mich überzeugt alles in einem Block abzuschicken. Ich habe ca 80 Selects die ich vorher absetzen muss. Dann würden entweder 130 bis 500 Inserts oder Updates abgesetzt werden. Ich denke mal das ich so viele Statemants mit einem Block absetzen kann wie ich will!?!

Zwar wird die Fehlerbehandlung dann etwas schwerer ( z.B. soll er manchmal ein Statemant einfach überspringen, wenn eine Spalte nicht existiert) aber trotsdem machbar. Außerdem müßte ich wissen, ob alles geinsertet wurde. Um entgültig sicher zu sein müßte ein einziges Kontrollstatement abgesetzt werden und das auch nur wenn die Verbindung während der Transaktion abreißt. Ist es auch möglich sich mehere Exceptionmeldungen wieder geben zu lassen?

Gruß
Wegalt
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#6

Re: Lockmode bei Updates

  Alt 4. Mär 2004, 14:49
Das wäre ein anonymer Block, der in einen Tabelle ein INSERT vornimmt und dir als Ouputvariable ein PseudoLog und die Anzahl der Fehler meldet (hier kann es ja nur max einer sein).

SQL-Code:
Declare
  RowsProcessed Number(6);
Begin
  :o_Log := Null;
  :o_ErrCount := 0;
  -- Hier beginn ein Unterblock
  Begin
    :o_Log := :o_Log || chr(10) || 'Test_Tab1 (INSERT):';
  
    Insert INTO Sheme0815.Test_Tab1 t
      (t.Text)
    VALUES
      (:i_NewText);
  
    -- da INSERTs implizierte cursor öffnen bekommst du mit...
    RowsProcessed := Sql%Rowcount;
    -- die Anzahl der Einträge die eingefügt/gelöscht/geändert wurden
    :o_Log := :o_Log || chr(10) || ' ' || RowsProcessed ||
              ' record(s) inserted...';
  
    -- Exception handling des Unterblock
  
  Exception
    When Others Then
      RowsProcessed := 0;
      :o_Log := :o_Log || chr(10) || --
                       ' ' || Replace(Sqlerrm, chr(10), chr(10) || ' ');
      :o_ErrCount := :o_ErrCount + 1;
      /* Das formatiert die Fehlermeldungen á la:
      Test_Tab1 (INSERT):
        ORA-01722: invalid number
      */

  
    -- Ende des Unterblock
  End;

  :o_Log := SubSTR(:o_Log, 2);
End;
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#7

Re: Lockmode bei Updates

  Alt 4. Mär 2004, 15:28
Bei mehreren INSERT pro Tabelle würde ich dir BULK SQL empfehlen.
:NewText wäre eine Index-By-Table, die als Variable an das Statement übergeben wurde.

SQL-Code:
FORALL i IN :NewText.First..:NewText.Last
   INSERT INTO Test_Table VALUES (:NewText(i));
Der Performancegewinn bei Bulk-SQL ist enorm -> bis zu 30-fache Geschwindigkeit gegenüber normaler DML.

Du kannst in einem anon. Block IMHO 128.000 Zeichen verwenden. Da passen also eine Menge Statements rein!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz