How to apply best transactional methods to read operations in Spring MVC using Hibernate?

As mentioned in blogs / books (e.g. Mark Richards's Java transactional design strategies), read operations must have the Propagation.SUPPORTS attribute.

In a simple Spring 3.1 MVC project with Hibernate 4.1, the script:

  • Declarative transaction management using @Transactional
  • sessionFactory of org.springframework.orm.hibernate4.LocalSessionFactoryBean
  • Transaction Manager org.springframework.orm.hibernate4.HibernateTransactionManager
  • Class of service with @Transactional (distribution = distribution .REQUIRED)
  • A function of this class of service that only retrieves a result set (performs a read operation) using @Transactional (distribution = distribution .SUPPORTS)
  • The read operation function returns a result set using sessionFactory.getCurrentSession (). get ()

Of course, when the controller performs the function of the read operation, the exception "No session for the current thread" occurs because the transaction is not started and the session was not received.

According to the configuration above (while it’s best, for example, non-invasive, less code, etc.), the attribute Propagation.SUPPORTS cannot be used unless the transaction has started using Propagation.REQUIRED or Propagation.REQUIRES_NEW.

How we use the use of Propagation.SUPPORTS for read operations without the need to start a transaction, for example. with Propagation.REQUIRED, but still taking advantage of declarative transaction management?

Thanks in advance.

Encoder, here is the configuration:

<tx:annotation-driven transaction-manager="txManager"/> <context:component-scan base-package="com.myapps.service.impl" /> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${db.driverClassName}" /> <property name="url" value="${db.url}" /> <property name="username" value="${db.username}" /> <property name="password" value="${db.password}" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mappingResources"> <list> <value>.....</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${db.dialect}</prop> <prop key="hibernate.format_sql">true</prop> </props> </property> </bean> 
+4
source share
2 answers

I do not agree with the use of SUPPORTS for read operations. Use REQUIRED.

  • In any case, a transaction is required to complete each database operation.
  • Performing a few small transactions to read several things at once will not benefit the first level cache
  • There will be no isolation between all subsequent readings, which means that something that is not visible to the first reading may become visible to the second
  • you will get lazy loading errors when passing associations
+5
source

A transaction is not always required for distribution. SUPER. Distribution of .SUPPORTS: support for the current transaction, execution of a transaction without a transaction if it does not exist.

0
source

Source: https://habr.com/ru/post/1414313/


All Articles