Db2 11.1

Optimistisches Sperren in JDBC-Anwendungen

Sie können JDBC-Anwendungen schreiben, um die Vorteile des optimistischen Sperrung für eine Datenquelle zu nutzen.

Optimistisches Sperren ist eine Technik, die Anwendungen verwenden können, um Sperren zwischen SELECT-und UPDATE-oder DELETE-Operationen freizugeben. Wenn sich die ausgewählten Zeilen ändern, bevor die Anwendung aktualisiert oder gelöscht wird, schlägt die Operation UPDATE oder DELETE fehl. Optimistisches Sperren minimiert die Zeit, während der eine bestimmte Ressource für die Verwendung durch andere Transaktionen nicht verfügbar ist.

Für Verbindungen zu einer Db2 für IBM® i -Datenquelle erfordert die Verwendung der optimistischen Sperrung Db2 für IBM i V6R1 oder höher.

Im Allgemeinen führt eine Anwendung die folgenden Schritte aus, um optimistisches Sperren zu verwenden:

  1. Wählen Sie Zeilen aus einer Tabelle aus.
  2. Release-Sperren für die Tabelle.
  3. Aktualisieren Sie die ausgewählten Zeilen, wenn sie sich nicht geändert haben.

Wenn Sie überprüfen möchten, ob sich die Zeile geändert hat, fragt die Anwendung das Zeilenänderungstoken ab. Das Zeilenänderungstoken ist nicht immer ein vollständig präziser Indikator dafür, ob sich die Zeile geändert hat. Wenn Sie eine Tabelle mit einer Zeitmarkenspalte für Zeilenänderung erstellen, ist das Zeilenänderungstoken vollständig korrekt. Wenn Sie die Tabelle ohne eine Zeitmarkenspalte für Zeilenänderung erstellen oder eine Tabelle ändern, um eine Zeitmarkenspalte für Zeilenänderung hinzuzufügen, spiegelt das Zeilenänderungstoken möglicherweise die Aktualisierungen einer Zeile möglicherweise nicht genau wider. Dies bedeutet, dass das Zeilenänderungstoken darauf hinweisen kann, dass sich eine Zeile geändert hat, auch wenn dies nicht der ist. Diese Bedingung wird als falsch negative Bedingung bezeichnet.

Wenn Sie eine JDBC-Anwendung schreiben, um ein optimistisches Sperren auszuführen, führen Sie ähnliche Schritte aus:

  1. Bereiten Sie eine Abfrage vor und führen Sie sie

    Geben Sie an, ob optimistische Sperrinformationen angezeigt werden sollen und ob diese Informationen falsche Negative enthalten können.

  2. Stellen Sie fest, ob die ResultSet optimistische Sperrinformationen enthält und ob diese Informationen falsche Negative erzeugen können.

    Basierend auf dem Typ der optimistischen Sperrinformationen können Sie entscheiden, ob die optimistische Sperrung fortgesetzt werden soll.

  3. Release-Sperren für die Tabelle.
  4. Aktualisieren Sie die ausgewählten Zeilen, wenn das Zeilenänderungs-Token angibt, dass sie sich nicht geändert haben.

Der folgende Code veranschaulicht, wie eine JDBC-Anwendung optimistisches Sperren ausführen kann. Die Zahlen in dem Beispiel entsprechen den zuvor aufgelisteten Schritten.

com.ibm.db2.jcc.DB2Statement s1 = 
  (com.ibm.db2.jcc.DB2Statement)conn.createStatement();
ResultSet rs = 
 ((com.ibm.db2.jcc.DB2Statement)s1).executeDB2OptimisticLockingQuery 
 ("SELECT EMPNO, SALARY FROM EMP WHERE EMP.LASTNAME = 'HAAS'", 
  com.ibm.db2.jcc.DB2Statement.RETURN_OPTLOCK_COLUMN_NO_FALSE_NEGATIVES);  1 
                                   // Geben Sie an, dass optimistisches
                                   // Sperren geplant ist und die Informationen
                                   // zum optimistischen Sperren keine
                                   // falschen negativen Werte generieren
                                   // sollen.
ResultSetMetaData rsmd = rs.getMetaData();
int optColumns =                                                           2 
  ((com.ibm.db2.jcc.DB2ResultSetMetaData)rsmd).getDB2OptimisticLockingColumns();
                                   // Informationen zum optimistischen Sperren
                                   // abrufen
boolean optColumnsReturned = false;

if (optColumns == 0);              // Verzichten Sie auf das optimistische Sperren
                                   // wenn keine Informationen zum optimistischen
                                   // Sperren zurückgegeben werden.
else if (optColumns == 1);         // Der Wert 1 wird bei Angabe von
                                   // RETURN_OPTLOCK_COLUMN_NO_FALSE_NEGATIVES
                                   // nicht zurückgegeben, da 1 angibt, dass
                                   // falsche negative Werte vorliegen können.
else if (optColumns == 2)          // Optimistisches Sperren ausprobieren,
   optColumnsReturned = true;      // wenn Informationen zum optimistischen
                                   // Sperren zurückgegeben werden und keine
                                   // falschen negativen Werte auftreten

rs.next();                         // Inhalt der Ergebnismenge abrufen
int emp_id = rs.getInt(1);
double salary = rs.getDouble(2);
 
long rowChangeToken = 0;
Object rid = null;
int type = -1;

if (optColumnsReturned) {          
  rowChangeToken =                 // Token für Zeilenänderung abrufen
    ((com.ibm.db2.jcc.DB2ResultSet)rs).getDB2RowChangeToken();
  rid = ((com.ibm.db2.jcc.DB2ResultSet)rs).getDB2RID();
                                   // RID abrufen, die die Zeile eindeutig
                                   // kennzeichnet
  int type = ((com.ibm.db2.jcc.DB2ResultSet)rs).getDB2RIDType ();
                                   // Datentyp der RID abrufen
}   
// ***************************************************
// Sperren freigeben oder Verbindung zur Datenbank trennen
// Abgerufene Daten nach Bedarf bearbeiten
// Verbindung zur Datenquelle wiederherstellen
// ***************************************************
…
PreparedStatement s2 = 
  conn.prepareStatement ("UPDATE EMP SET SALARY = ? " +
  "WHERE EMPNO = ? AND ROW CHANGE TOKEN FOR EMP = ? and " +
  "RID_BIT(EMP) = ?");
                                   // Anweisung zum Aktualisieren der
                                   // zuvor ausgewählten Zeilen, die
                                   // nicht geändert wurden
s2.setDouble(1, salary+10000);
s2.setInt(2, emp_id);
                                   // Neue Zeilenwert festlegen
s2.setLong(3, rowChangeToken);
                                   // Token für Zeilenänderung der
                                   // zuvor abgerufenen Zeile festlegen
if (type == java.sql.Types.BIGINT)
  s2.setLong (4, ((Long)rid).longValue());
else if (type == java.sql.Types.VARBINARY)
  s2.setBytes (4, (byte[])rid);
                                   // RID der zuvor abgerufenen Zeile
                                   // festlegen
                                   // Für RID-Datentyp geeignete
                                   // setXXX-Methode verwenden
int updateCount = s2.executeUpdate();                                       3 
                                   // Aktualisierung durchführen
if (updateCount == 1);             // Erfolgreiche Aktualisierung
else                               // Fehlgeschlagene Aktualisierung
…