TSQL WÄHLEN Sie dann UPDATE in einer Transaktion, dann wieder AUSWÄHLEN

Bin ich wirklich Mühe mit einer Abfrage in meinem ColdFusion-Anwendung (backended zu MS SQL 2008). Ich bekomme den DB-deadlock-Fehler an dieser Transaktion:

<code>
<cftransaction>
   <cfquery name="selectQuery">
      SELECT TOP 20 item_id, field2, field3
      FROM Table1
      WHERE subject_id = #subject_ID# AND lock_field IS NULL AND
            NOT EXISTS (SELECT * FROM Table2 WHERE Table2.user_ID = #user_ID# Table1.item_id = Table2.item_id)
   </cfquery>

   <cfquery name="updateQuery">
      UPDATE Table1
      SET lock_field = 1, locked_by = #user_ID#
      WHERE Table1.item_id IN (#ValueList(selectQuery.item_id#)
   </cfquery>
</cftransaction>
</code>

Bascially, ich habe eine Tabelle (Tabelle1), die für einen großen Schlange der wartenden Elemente. Der Benutzer "zur Kasse" - Elemente, um Ihnen eine Punktzahl. Nur ein Benutzer kann ein Element ausgecheckt zu einer Zeit. Ich brauche auf Anfrage einen block von 20 Elementen, die zu einem Zeitpunkt für einen bestimmten Benutzer. Diese Elemente können bereits überprüft werden und der Benutzer kann bereits erzielte Sie vor (daher der lock_field IST NULL-und not EXISTS-Anweisung im SELECT). Einmal habe ich bestimmt die Liste der 20 item_ids, muss ich dann update der queue-Tabelle zu markieren, die Sie als gesperrt, so dass niemand sonst prüft Sie bei der gleichen Zeit. Ich auch zurückgeben müssen, die Liste der item_ids.

Ich dachte, es funktioniert vielleicht besser, wenn ich zog diese aus einer cftransaction, um eine gespeicherte Prozedur auf dem SQL Server-Seite. Ich bin mir nur nicht sicher, ob die cftransaction Verriegelung stört irgendwie. Ich bin kein TSQL-guru, so dass etwas Hilfe würde geschätzt werden.

  • Haben Sie eine <cflock scope="application"> im Ort zu schützen Sie Ihre UPDATE-Vorgang? Auf diese Weise werden alle concurrency-Probleme sollten Weg gehen.
  • Das update ist Teil der cftransaction. Ich bin mir nicht sicher, ob ein cflock erforderlich ist, nicht?
  • Ein cftransaction lediglich ein Rollback für jede SQL-Anweisung ausgegeben, die innerhalb es, sobald ein Fehler Auftritt. Es sperrt nicht, dass code-Abschnitt.
  • Ja, aber die Verriegelung in Frage nicht-CF-variable sperren, es Datenbank-sperren. Ich bin nicht versuchen, den Zugriff/Aktualisierung der CF-vars in dieses problem.
  • Es ist wahrscheinlich eine Transkription Fehler, aber Sie ' re fehlt eine Klammer in der update-query.
  • Ich Stimme mit Tomalak. Sie haben vermutlich eine race-condition geht. Am besten single-thread-dieses Stück code mit CFLOCK.
  • Lewis: Sie sind nicht nur sperren von Variablen den Zugriff mit <cflock> - Sie stellt sicher, dass nur ein thread kann immer Zugriff auf diesen code-Abschnitt, der zu einem bestimmten Zeitpunkt. Alle anderen threads müssen warten, bis der einen verlassen hat, den gesperrten Abschnitt. Es scheint wie ein guter Fall für single-threaded-Zugriff. Natürlich bedeutet dies die überführung einer Applikation-große, exklusive Sperre.

InformationsquelleAutor Bryan Lewis | 2009-11-16
Schreibe einen Kommentar