CPS-899 Start and stop sessions on Java API

CPS-899 Start and stop sessions on Java API

 

References:

Sessions

  • Short life session

    • LazyInitialization exception

    • write changes to DB every step

  • Open-Session-in-View

  • Extended session

    • session is never closed

    • manual session.flush (send all open statements to DB)

    • session stay in persistent state

Hibernate's Session

  • Session allows physical connection with a database

    • only creates connection when required

  • openSession()/getCurrentSession()

  • session.close()

  • Session cannot be kept as it is not threadsafe

  • Perform all crud operations (read, update and delete operations)

  • HibernateContentQueryFactory

    • can use a provided EntityManager object to create a query

  • Object states

    • Transient - when object unattached to any session

    • Persistent

      • attach object to a session with 'persist' or 'save' method

    • Detached

      • object is not managed by any session

        • session.close();

Transactions

Transactions allows for grouping of operations

  • All SQL statements execute inside a transaction

  • transaction is either completely committed or rolled back

 

Transaction isolation levels

  • All JDBC connection initialises with the default isolation level of the DBMS used but can be configured

Which isolation level?

  • Read uncomitted isolation

    • allows a transaction to read uncomitted data (dirty read) but not lost updates

    • can be implemented with write locks

  • Read committed isolation

    • transaction executes two nonrepeatble reads but not dirty reads

    • can be implemented with shared read locks and write locks

      • read transactions does not restrict other transactions from reading

      • uncomitted update/write transaction restricts other transactions from accessing the row

  • Repeatable read isolation

    • allows neither unrepeatable reads nor dirty reads

      • read transactions does not restrict other transactions from reading but restricts from updating/writing

      • write transaction blocks all

  • Serializable isolation

Plain JDBC Transaction

  • java.sql.Connection

  • transaction is tarted with setAutoCommit(false) on aJDBC connection 

  • transaction is ended with commit()

  • immediate rollback - rollback() 

  • Isolation levels

    • e.g. connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);

  • Save point (Nested transactions in spring

    • e.g. connection.setSavepoint();

 

Hibernate

  • JDBC Connection for every session

  • Transaction interface is customizable to implement own TransactionFactory

  • beginTransaction() call on session instance

    • equivalent to setAutoCommit(false) on plain JDBC transaction

    • Session is bound to the transaction

    • after commit or rollback connection is released

    • closing session detaches all other resource/all managed persistent instances

  • rollback()

  • any hibernate operation can throw a RunTimeException

  • setTimeout() - sets the time in seconds for a transaction is allowed to run

  • Isolation level can be configured and all connections and transactions will be affected

    • e.g. hibernate.connection.isolation = 4

  • lock()

    • can be set with query statement

      • .setLockOptions() 

    • LockMode.UPGRADE

      • sets a lock on the row(s) that represents the Entity instance

      • e.g. session.buildLockRequest(LockOptions.UPGRADE).lock(entityName)

    • LockMode.READ

    • LockMode.UPGRADE_NOWAIT

      • disables waiting for concurrent lock releases, throws exception when it cannot get a lock

      • automatically falls to LockMode.UPGRADE if DB does not support NO_WAIT

    • LockMode.FORCE

    • LockMode.WRITE

 

Spring/Spring Boot Transaction Management

Annotation '@Transactional'

  • Spring '@Transactional' annotation handles the following transactions based on raw JDBC transaction

    Connection connection = dataSource.getConnection(); try (connection) { connection.setAutoCommit(false); // execute some SQL that e.g. // inserts the user into the db and retrieves the autogenerated id // userDao.save(user); connection.commit(); } catch (SQLException e) { connection.rollback(); }
  • We can use this annotation at either a class or method level

  • requires specification of transaction manager in spring configuration

    • '@Configuration'

    • '@EnableTransactionManagement'

  • Supports the following configurations

    • Propagation type

      • '@Transactional(propagation = Propagation.REQUIRED)'

        • method opens a new transaction using the same existing connection

      • '@Transactional(propagation = Propagation.REQUIRES_NEW)'

        • opens new transaction in a new connection

      • '@Transactional(propagation = Propagation.MANDATORY)

        • does not open a new transaction, requires a pre-existing transaction to invoke method or else Spring throws an exception

    •  Isolation level

      • '@Transactional(isolation = Isolation.SERIALIZABLE)'

      • Postgres default isolation level is 'READ COMMITTED'

    • Timeout

    • readOnly flag

    • Rollback rules

      • 2 ways to rollback transaction

        • declarative

          • '@Transactional(rollbackFor = { SQLException.class })'

        • programmatic

          • uses 'TransactionAspectSupport'

 

Spring and Hibernate Transaction Management

Allows syncing of Spring's '@Transactional' and Hibernate or JPA

  • HibernateTransactionManager

    • Ensures management of transaction via Hibernate (SessionFactory)

      • creates a Session instance

      • opens a transaction (setAutocommit(false))

      • invokes transactional methods

      • commits transaction

      • close session/jdbc connection

    • Allows Spring code to use same transaction in non-hibernate

      • can use HQL or jdbc template

Gliffy Diagram is only supported by the cloud editor

Because Forge macros arent supported by the legacy editor, you'll need to convert this content to the cloud editor to display this macro properly. Find out more about converting to the cloud editor

Postgresql lock

BEGIN; SET LOCAL lock_timeout = '4s'; <SELECT FOR UPDATE> <UPDATE> COMMIT;
  • SELECT FOR UPDATE

    • locks rows from another transaction that attempts to lock

  • SET LOCAL lock_timeout = '4s';

  • Pessimistic lock with skip locked

    • i.e. "select * from sampleTable where used=false for update skip locked limit 1" 

      • skip the one that's locked and move on

Spring data '@lock' annotation

  • method level

    • sets the lock mode type for the target query

      • pesssimistic lock modes

        • pessimistic_read

        • pessimistic_write

        • pessismitic_force_increment

        • pessimistic_write

    • timeouts

      • use of '@QueryHints'

  • can be used on overwritten CrudRepository methods