Persists mit Rollback?

Ich habe mal unter Netbeans 8 mir eine Funktion erzeugen lassen für persistst Entity

Netbeans erzeugt folgenden Code

    public void persist(Object object) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPAEclipseLinkMySQL_JPAEclipseLinkMySQL_jar_0.0.0.1-SNAPSHOTPU");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        try {
            em.persist(object);
            em.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            em.getTransaction().rollback();
        } finally {
            em.close();
        }
    }

Was ich nicht so ganz verstehe wieso em.persists(object) zusammen mit Transaction verwendet wird???

kommt immer auf die Vorgehens-Modelle an,
gerade nach einem Link gesucht lese ich

Database (or system) transaction boundaries are always necessary. No communication with the database can occur outside of a database transaction (this seems to confuse many developers who are used to the auto-commit mode). Always use clear transaction boundaries, even for read-only operations. Depending on your isolation level and database capabilities this might not be required but there is no downside if you always demarcate transactions explicitly. You’ll have to do operations outside a transaction, though, when you’ll need to retain modifications in an EXTENDED persistence context.

Chapter*5.*Transactions and Concurrency

allerdings bezieht sich das wohl nur auf die DB, der Rest dahinter klingt schon eher als wäre in EntityManager nicht immer Transaction nötig,
dahingestellt, ob sie noch intern zur DB aufgebaut wird oder nicht


wie ich es von Hibernate kenne:
ohne Transaction ist für mich zumindest Read-Only, wobei ich gar nicht erst ausprobiere etwas (mit Session.save()) zu speichern,
im Zweifel immer mit Worst Case zu rechnen: wenn man was speichern will, geht es garantiert (oder noch schlimmer: manchmal) verloren,
wenn man aber etwas nicht speichern/ nicht löschen will, dann sollte man es auch nicht tun, sonst nach Murphys Gesetz bestimmt auch schiefgehend, wird doch gelöscht…,

als Steigerung noch schlimmer vielleicht nur teilweise Speicherungen/ Löschungen, rein zufällig oder je nachdem was geflusht wurde (flush() auch ein Befehl der zu kennen ist)


einfache Regel: wenn etwas zu ändern ist oder wenn unklar was passieren wird (Aufruf variabler Untermethoden, die in Verdacht stehen evtl. etwas zu ändern usw.), für den Anfang ruhig immer, dann Transaktion öffnen,

und das Ende ist leicht: wenn evtl. Änderungen gespeichert werden sollen, dann Commit, sonst Rollback,

und auch wieder: immer zur Sicherheit eins ausführen,
falls vergessen/ durch Exception übersprungen, Transaktion so ausgelaufen, dann (im angenommen Worst Case) genauso übel wie ohne Transaktion…


von gewisser Problematik sind auch Schachtelungen:
angenommen die gepostete persist-Methode ist innerhalb einer laufenden Transaktion aufgerufen, welche später mit Rollback geschlossen wird,
dieses persist hier dann immer noch persistent?
wird das Commit hier gar Änderungen vor dieser Methode persistieren? wohl kaum

gewiss gibt es auch dazu ein überzeugendes Modell, lohnt sich alles zu suchen und nachzulesen,

bisher konnte ich mich davon noch feige fernhalten :wink: , in meinen Programmen ist es meist eher einfach gehalten:
es gibt höchstens eine Transaktion außen herum, evtl. zwischendurch für alles Zwischenstand committet und weiter, auf keinen Fall für so kleine Einzel-Methoden Extrawurst,

wenn trotz Rollback am Ende noch etwas zu speichern ist, etwa Log-Einträge, dann diese danach,
aber mitten drin wäre zugegeben auch manchmal komfortabel, eh noch nicht häufig dazu gekommen :wink:

Natürlich werden auch “persistierte” Änderungen im Falle eines Falles wieder zurückgerollt, dafür sind ja Transaktionen auch da.