Auto-commit mode makes each SQL statement its own short database transaction. It suits ad hoc SQL-console work, where statements are not planned as one atomic unit. section 11.3
In JDBC and JPA/Hibernate access, auto-commit mode has these practical consequences:
- Provides atomicity for each individual SQL statement, but does not make a sequence of statements atomic or isolated as one unit. section 11.3
- Allows reads through find(), getReference(), refresh(), queries, lazy proxies, and collections when the persistence context is unsynchronized. section 11.3.1
- Prevents automatic flushing in an unsynchronized persistence context; manually flushing changes or acquiring non-NONE locks raises TransactionRequiredException. section 11.3.1
- Can show current scalar database values while returning an already-managed entity with its in-memory state, so scalar queries and entity reads differ. section 11.3.1
Reading and discarding an in-memory change
Create an EntityManager without an active transaction, load an Item, change its name, and query both scalar and entity results. The scalar query can return the original database value, while the managed entity retains the changed name. Calling flush() fails; refresh(item) reloads the database state and discards the change. section 11.3.1
Listing 11.7 Reading data in auto-commit mode
Path: Ch11/transactions4/src/test/java/com/manning/javapersistence/ch11 /concurrency/NonTransactional.java EntityManager em = emf.createEntityManager(); #1 Item item = em.find(Item.class, ITEM_ID); #2 item.setName("New Name"); assertEquals( #3 "Original Name", em.createQuery("select i.name from Item i where i.id = :id", String.class) .setParameter("id", ITEM_ID).getSingleResult() ); assertEquals( #4 "New Name", em.createQuery("select i from Item i where i.id = :id". Item.class) .setParameter("id", ITEM_ID).getSingleResult().getName() ); // em.flush(); #5 em.refresh(item); #6 assertEquals("Original Name", item.getName()); em.close(); #1 No transaction is active when creating the <kbd>EntityManager</kbd>. #2 Access the database to read data. #3 Because the context is unsynchronized, flushing doesn’t occur, and the query returns the old, original database value. #4 The already-loaded <kbd>Item</kbd> instance with the changed name is returned from the persistence context; values from the database are ignored. #5 You cannot execute an <kbd>UPDATE</kbd> in unsynchronized mode, because you wouldn’t be able to roll back the change. #6 Roll back the change you made with the <kbd>refresh()</kbd> method.
Use the Java listing to trace EntityManager creation, entity loading, scalar versus entity queries, the prohibited flush, and refresh(). section 11.3.1
