emilly emilly - 1 year ago 61
Java Question

Why transaction here is treated as two separate transactions?

Here I have below method in spring controller

public Customer updateCustomer(Custom customer) throws Exception {


I have below method in helper class

@Transactional(readOnly = false)
public Department updateDepartment(Department department) throws Exception {


What i am observering is as soon as thread comes out of method
, changes under that method getting committed. I am not sure
why ? As default propagation is
which means that
Support a current transaction, create a new one if none exists.

Then how come transaction for method
is separate from method

I am using JPA( hibernate implementation) with spring transaction. Also i don't see explicitly setting behaviour
in xml

Relevant section of transaction management from spring configuration

<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />

<tx:annotation-driven transaction-manager="txManager" />

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources" value="META-INF/custom-mappings.hbm.xml" />
<property name="packagesToScan" value="com..., ...Other packages" />
<property name="jpaVendorAdapter">
<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="jpaProperties">
<prop key="org.hibernate.envers.default_schema">${jdbc.audit.schema}</prop>
<prop key="hibernate.session_factory_name">SessionFactory</prop>
<property name="jpaPropertyMap">
<entry key="javax.persistence.validation.factory">
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

I have configuration file related to controller also

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

Answer Source

It is uncommon to have @Transactional annotations on controller methods. The common usage it to put transaction demarcation at service level.

Transactional controllers are possible but have some caveats. First, Spring transaction management is based on Spring AOP and uses JDK proxies by default. It works fine at service level, because services are injected as interfaces in controller. But controllers are not injected as interfaces, so it will not work and you will have to use class target proxying with CGLib proxies for it works. Having controller implementing interfaces with JDK proxies has been reported to work on some Spring versions and fail on other: see this other post

TL/DR: unless you really cannot put transaction demarcation at service level and not at controller level.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download