61 Stimmen

Gibt es eine Möglichkeit, Zeilen gleichzeitig zu SELECT und UPDATE zu machen?

Ich möchte eine Reihe von Zeilen auf der Grundlage eines einfachen Kriteriums aktualisieren und die Liste der PKs erhalten, die geändert wurden. Ich dachte, ich könnte einfach so etwas tun, aber bin besorgt über mögliche Gleichzeitigkeitsprobleme:

SELECT Id FROM Table1 WHERE AlertDate IS NULL;
UPDATE Table1 SET AlertDate = getutcdate() WHERE AlertDate IS NULL;

Wenn das in einer Transaktion verpackt ist, gibt es irgendwelche Gleichzeitigkeitsprobleme, die auftreten können? Oder gibt es eine bessere Möglichkeit, dies zu tun?

1 Stimmen

Ich denke, das ist bisher die beste Lösung stackoverflow.com/questions/22066397/

3voto

Kanagavelu Sugumar Punkte 17711

Ich bin mit dem gleichen Problem konfrontiert; ich muss den Kreditbetrag aktualisieren und die geänderte Zeit zusammen mit den Kreditdetails aus der DB abrufen. Es ist im Grunde

SYNCHRONOUS/ATOMICALLY durchführen (UPDATE dann GET) in MYSQL

Ich habe viele Optionen ausprobiert und eine gefunden, die mein Problem gelöst hat.

1) OPTION_1 ZUR AKTUALISIERUNG AUSWÄHLEN

Dies ist die Aufrechterhaltung der Sperre bis Update (SYNC von GET zu UPDATE), aber ich brauche Sperre nach Update bis die GET.

2) OPTION_2 Gespeicherte Prozedur

Gespeicherte Prozedur wird nicht synchron wie Redis Lua ausgeführt, so dass auch wir Sync-Code benötigen, um das durchzuführen.

3) OPTION_3 Transaktion

Ich habe JPA entityManager wie unten verwendet, dachte, dass vor Commit niemand aktualisieren kann, und vor Commit werde ich das aktualisierte Objekt zusammen mit geänderten Zeit (von DB) erhalten. Aber ich habe nicht das neueste Objekt erhalten. Nur Commit habe ich die neuesten.

    try {
        entityManager.getTransaction().begin();
        //entityManager.persist(object);
        int upsert = entityManager.createNativeQuery(
        "update com.bill.Credit c set c.balance = c.balance - ?1
          where c.accountId = ?2 and c.balance >= ?1").executeUpdate(); 
             //c.balance >= ? for limit check
        Credit newCredit = entityManager.find(Credit.class, "id");
        entityManager.refresh(newCredit); //SHOULD GET LATEST BUT NOT
        entityManager.getTransaction().commit();
    } finally {     
        entityManager.unwrap(Session.class).close();
    } 

4) OPTION_4 LOCK hat das Problem gelöst, d.h. vor der Aktualisierung habe ich die Sperre erworben; nach GET habe ich die Sperre wieder freigegeben.

private Object getLock(final EntityManager entityManager, final String Id){

    entityManager.getTransaction().begin();
    Object obj_acquire = entityManager.createNativeQuery("SELECT GET_LOCK('" + Id + "', 10)").getSingleResult();
    entityManager.getTransaction().commit();
    return obj_acquire;
}

private Object releaseLock(final EntityManager entityManager, final String Id){

    entityManager.getTransaction().begin();
    Object obj_release = entityManager.createNativeQuery("SELECT RELEASE_LOCK('" + Id + "')").getSingleResult();
    entityManager.getTransaction().commit();
    return obj_release;
}

0 Stimmen

MySQL ? Die Frage ist getaggt für SQL SERVER

0 Stimmen

OHH MY BAD, Antwort ist für MySQL

1voto

Edit: mein Fehler, Sie wollten, dass der Select die Ergebnisse nach der Aktualisierung anzeigt, nicht die Aktualisierung von einem Select.

Haben Sie es mit einer Unterauswahl versucht?

update mytable set mydate = sysdate 
where mydate in (select mydate from mytable where mydate is null);

0voto

zappan Punkte 3608

Wenn es innerhalb der Transaktion ist, kümmert sich das Datenbanksperrsystem um Gleichzeitigkeitsprobleme. natürlich, wenn Sie eine verwenden (die mssql-Standardeinstellung ist, dass es Sperre verwendet, so dass es angibt, wenn Sie das nicht überschreiben)

0voto

In SQL 2008 wurde eine neue TSQL-Anweisung "MERGE" eingeführt, die Einfüge-, Aktualisierungs- oder Löschoperationen in einer Zieltabelle auf der Grundlage der Ergebnisse einer Verknüpfung mit einer Quelltabelle durchführt. Sie können zwei Tabellen synchronisieren, indem Sie Zeilen in einer Tabelle einfügen, aktualisieren oder löschen, die auf den in der anderen Tabelle gefundenen Unterschieden basieren.

http://blogs.msdn.com/ajaiman/archive/2008/06/25/tsql-merge-statement-sql-2008.aspx http://msdn.microsoft.com/en-us/library/bb510625.aspx

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X