Hibernate: Deadlock gefunden, wenn Sie versuchen zu erhalten lock

Ich bin mit hibernate in meinem Projekt, und ich bin immer zufällig Scheinbare Deadlocks für sehr einfache Datenbank-Operationen.

Es ist eine der Stack-Traces: https://gist.github.com/knyttl/8999006 – Was mich verwirrt, dass die erste Ausnahme ist RollbackException und dann gibt es LockAquisition Ausnahmen.

Das problem tritt oft auf ähnliche Klauseln:

@Transactional
public void setLastActivity() {
    User user = em.findById(...);
    user.setLastActivity(new Date());
    em.merge(user);
    em.flush();
}

Bin ich ziemlich festgefahren, da ich nicht weiß, ob es ein problem von Hibernate, MySQL oder C3P0.

Mein Hibernate-Konfiguration:

            <prop key="hibernate.dialect">${database.dialect}</prop>
            <prop key="hibernate.hbm2ddl.auto">${database.structure}</prop>
            <prop key="hibernate.connection.url">${database.connection}</prop>
            <prop key="hibernate.connection.username">${database.username}</prop>
            <prop key="hibernate.connection.password">${database.password}</prop>
            <prop key="hibernate.connection.driver_class">${database.driver}</prop>
            <prop key="hibernate.connection.shutdown">true</prop>
            <prop key="hibernate.connection.writedelay">0</prop>
            <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
            <prop key="hibernate.connection.charSet">UTF-8</prop>
            <prop key="hibernate.show_sql">${database.show_sql}</prop>
            <prop key="hibernate.format_sql">false</prop>
            <prop key="hibernate.ejb.metamodel.generation">disabled</prop>
            <!-- Use the C3P0 connection pool provider -->
            <prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
            <prop key="hibernate.c3p0.min_size">0</prop>
            <prop key="hibernate.c3p0.max_size">50</prop>
            <prop key="hibernate.c3p0.timeout">120</prop>
            <prop key="hibernate.c3p0.max_statements">0</prop>
            <prop key="hibernate.c3p0.max_statementsPerConnection">0</prop>
            <prop key="hibernate.c3p0.maxStatementsPerConnection">0</prop>
            <prop key="hibernate.c3p0.idle_test_period">120</prop>
            <prop key="hibernate.c3p0.acquire_increment">1</prop>
            <prop key="hibernate.c3p0.numHelperThreads">8</prop>

EDIT1:

  • Ich oben schrieb, gab es Scheinbare Deadlocks geschieht - das war falsch, nur ein "Deadlock gefunden, wenn Sie versuchen zu erhalten lock" passieren.

EDIT2:

Dies geschieht auch auf diese Methoden - diese BEDÜRFNISSE werden annotiert mit @Transactional:

@Transactional
public void setLastActivity() {
    em.insertNative("table")
           .values(...)
           .execute();
}
  • Sie brauchen, um mehr details zu liefern, wie die tatsächliche Ausnahmen, die Sie immer mit stacktrace. Hier meine ich, nicht auf eine externe Website, die blockiert werden durch Unternehmens-firewalls.
  • Sie wahrscheinlich wollen, setzen Sie autocommit=false.
  • Gimby: Der stacktrace ist gegeben - sehen eher vorsichtig. brettw: Können Sie uns mehr Informationen, warum sollte es helfen?
  • Sie verwenden den Begriff "Scheinbarer Deadlock", aber das scheint nicht in Ihrem Kern. sehen Sie, SCHEINBARER DEADLOCK-Meldungen von c3p0 irgendwann? wenn dem so ist, können Sie reproduzieren, dass mit den langen status-Nachricht folgt?
  • Können Sie zeigen Sie Ihren code. Wie Sie öffnen und schließen Sie eine Sitzung/Transaktion.
  • Steve: Bitte siehe meine edits. Zeus: Sehen Sie den bearbeiteten code - es geschieht in diesem einfachen Methoden.
  • Was passiert, wenn Sie loszuwerden, die @Transactional? Hatte deadlocks mit hibernate vor kurzem wegen @Transactional-Annotationen.
  • einige Geschäfte in der Anwendung könnte sein, die sperren halten für eine lange Zeit, Erhöhung der Quote von deadlock. Transaktional verwendet wird, mit " nicht-Standard-isolation irgendwo? Auch könnten Sie nach dem code, code FollowRemote.getFollowsFor, und die Zeile 186 in dieser Methode erwähnt im stacktrace
  • es ist etwas seltsam, in der setLastActivity Methode, Nutzer einer angeschlossenen Einheit, so gibt es keine Notwendigkeit, es zu verschmelzen als die Verschmelzung hat keine Auswirkungen auf angeschlossene Einheiten. Auch flush kurz vor dem Ende der Methode nicht benötigt wird, wie der Frühling wird, machen den flush für uns. Gibt es einen speziellen Grund, warum das manuelle Spülen wird? es könnte im Zusammenhang
  • Jan Vladimir Moster: Auch wenn ich es entfernt, ich war immer "Keine Transaktion ist im Gange." Ausnahmen – ich dachte, dass beim Zugriff auf entity-manager, da muss immer ich die Transaktion?
  • jhadesdev: In der Methode, es gibt nur einfache select-Anweisung, und die Methode ist nicht @Transactional.
  • Es scheint, dass, wenn ich rufe native SQL-update, die Methode muss annotiert werden, die mit @Transactional, sonst bin ich immer: Executing an update/delete query Ausnahmen.
  • was ist Ihre Isolationsstufe der Transaktion , ist diese Multi-Thread-Umgebung ? haben Sie sah in die Datenbank , gibt es keine Sperre in diesem moment ?

InformationsquelleAutor Vojtěch | 2014-02-14
Schreibe einen Kommentar