2012-03-29 2 views
1

Verwenden der Oracle-Datenbank. Hier ist, wie ich denke, die SQLException passiert ...Cache-Tabellen mit parallelen Diensten, die Probleme verursachen. eindeutige Einschränkung SQLException. Spring JDBC

Angenommen, ich habe zwei Instanzen eines Dienstes parallel ausgeführt. Beide tun folgendes:

  1. Abfrage Cache (B), um zu sehen, ob Person dort existiert.
  2. Wenn eine Person vorhanden ist, aber nicht mehr aktuell ODER existiert nicht = eine Abfrage in der Hauptdatenbank (A) ausführen.
  3. Wenn Person in der Datenbank gefunden (A) und nicht früher im Cache gefunden (B). INSERT, sonst, wenn eine Person früher im Cache gefunden wurde, aber ein veralteter UPDATE-Cache war.

Ich verwende den folgenden Code, um die Entscheidung zu treffen, basierend auf früheren Abfrage-Cache B.

void insertOrUpdate(RegistryPersonMo person) { 
    if (person.getId() == null) { 
     insertPerson(person); 
    } else { 
     updatePerson(person); 
    } 
} 

und einfügen Frühling JDBC mit:

void insertPerson(RegistryPersonMo person) { 
    Number id = insertInto("PERSON_REGISTRY", "RAAMAT").usingGeneratedKeyColumns("ID").executeAndReturnKey(usingParameters(person)); 
    if (id != null) { 
     person.setId(id.longValue()); 
    } 
} 

Das eigentliche Problem tritt auf, wenn zwei Instanzen des Dienstes haben die Abfrage des Cache beendet (B) und die Person wurde nicht gefunden (null). Dann führt eine Instanz einen INSERT durch, weil Daten nicht existierten. Der andere erhält SQLException, wenn er versucht, dasselbe zu tun, weil bereits ein Eintrag mit einer eindeutigen Einschränkung existiert.

Weiß jemand, was die beste \ standardumgehung ist? Einige Ideen, die ich gehabt habe:

  • Lock Lesen der Zeile bis Einfügen durchgeführt. Kann ich das mit Spring machen?
  • Verwenden ersetzen oder einfügen mit ignorieren. Lernen Sie immer noch, gibt es irgendwelche Nachteile für diese?

Beachten Sie mag Ich mag Frühling verwenden und die Abfrage so weit wie möglich zu automatisieren ..

Antwort

1

Ich denke, es ist nur in dieser Situation in Ordnung, die eindeutige Einschränkung Ausnahme zu ignorieren. Ja, das ist Race Condition, aber das erwartete - gewünschte Ergebnis wird erreicht, Record eingefügt. Loggen Sie sich vielleicht ein, um sagen zu können, wie oft das passiert.

Locking oder Transaktion Serialisierung würde dieses Problem lösen, wird aber in diesem Fall meiner Meinung nach nicht viel Sinn machen.

+0

Also schlagen Sie vor, nur die Ausnahme zu fangen? – ollo

+0

Ja. Fang und logge dich ein. Abhängig von Ihrem Nutzungsszenario werden Sie fast nie sehen, dass es tatsächlich passiert (wenn die Anfrage für eine Person zufällig zu einem der Server kommen würde) oder Sie würden sehen, dass es viel passiert (wenn Anfragen für dieselbe Person gleichzeitig kommen würden) zu beiden Servern). Wenn sich herausstellt, dass es sich um ein Problem handelt, könnten Sie darüber nachdenken, wie Sie es weiter angehen können. – maximdim

+0

Vielen Dank, mein Herr. – ollo

Verwandte Themen