@Transactional Spring does not create a new transaction

Any help with this would be greatly appreciated. Iam using Spring, Jetty (Eclipse Jetty Plugin). It seems that the declarative transaction management @Transactional does not work.

It is confirmed that this does not work in two ways: 1. After calling the method, the newly created entity is not dumped to the database. 2. TransactionSynchronizationManager.isActualTransactionActive (); returns false

Note that the method described below is different from the @Controller class when invoking an HTTP request ultimately calls this save method. The controller class does not implement any interfaces. Actual code:

@Transactional(propagation = Propagation.REQUIRES_NEW) public void save(PERule peRule) { boolean inTransaction = TransactionSynchronizationManager.isActualTransactionActive(); peRuleDAOImpl.persist(peRule); } 

The absence of a transaction is also confirmed by the output of the log:

 DEBUG: org.hibernate.internal.SessionImpl - Opened session at timestamp: 13762325621 DEBUG: org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl - Skipping JTA sync registration due to auto join checking DEBUG: org.hibernate.ejb.AbstractEntityManagerImpl - Looking for a JTA transaction to join DEBUG: org.hibernate.ejb.AbstractEntityManagerImpl - Unable to join JTA transaction DEBUG: org.hibernate.event.internal.AbstractSaveEventListener - Delaying identity-insert due to no transaction in progress 

However, when I programmatically determine the explicit boundaries of transactions and commit the transaction, the object is painted over to the database. For instance:

 @Resource private PlatformTransactionManager txManager; private void save(PERule peRule) { DefaultTransactionDefinition def = new DefaultTransactionDefinition(); TransactionStatus status = txManager.getTransaction(def); def.setName("SomeTxName"); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); try { peRuleDAOImpl.persist(peRule); } catch (Exception ex) { txManager.rollback(status); } txManager.commit(status); } 

Therefore, this does not seem to be a problem with the way I defined my transactionManager, since it can be injected into an object as defined above.

ContextConfig: root-context.xml

 <aop:aspectj-autoproxy /> <context:annotation-config /> <context:component-scan base-package="org.springframework.samples.mvc, com.project.*" /> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>/WEB-INF/spring/proddatabase.properties</value> </property> </bean> <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/myds" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="persistenceUnitName" value="EconDatesDB" /> <property name="persistenceXmlLocation" value="/WEB-INF/spring/jpa-prod-persistence.xml" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="generateDdl" value="false" /> <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" /> </bean> </property> <property name="jpaProperties"> <props> <prop key="hibernate.format_sql">false </prop> <prop key="hibernate.use_sql_comments">false </prop> <prop key="hibernate.generate_statistics">false </prop> <prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory </prop> <!-- The following line is what used in Hibernate 4 instead of a TransactionManagerLookup class --> <prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup </prop> </props> </property> </bean> <tx:annotation-driven mode="aspectj" proxy-target-class="true" transaction-manager="transactionManager"/> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager" ref="atomikosTransactionManager" /> <property name="userTransaction" ref="atomikosUserTransaction" /> </bean> <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> <property name="transactionTimeout" value="300" /> </bean> <!-- Construct Atomikos UserTransactionManager, needed to configure Spring --> <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close"> <!-- when close is called, should we force transactions to terminate or not? --> <property name="forceShutdown" value="false" /> <property name="transactionTimeout" value="300" /> </bean> <mvc:annotation-driven /> <beans:bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <beans:property name="formatters"> <beans:bean class="org.springframework.samples.mvc.convert.MaskFormatAnnotationFormatterFactory" /> </beans:property> </beans:bean> <!-- Controllers.xml Only contains routes from path to view name, and has no other spring config <mvc:view-controller path="showcase/" view-name="/WEB-INF/views/home" /> --> <beans:import resource="/appServlet/controllers.xml" /> 

servlet context:

  <resources mapping="/resources/**" location="/resources/" /> <resources mapping="/sharedResources/**" location="/parkingEngine/resources/" /> <beans:bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="order" value="1" /> <!-- <beans:property name="prefix" value="/WEB-INF/views/" /> --> <beans:property name="prefix" value="" /> <beans:property name="suffix" value=".jsp" /> </beans:bean> 

web.xml:

  <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/root-context.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> 

pom.xml related dependencies:

 <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.10</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.6.10</version> </dependency> 

I also tried the following tx variations: annotation-driven in my root context. xml:

 <tx:annotation-driven mode="aspectj" proxy-target-class="true" transaction-manager="transactionManager"/> <tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager"/> <tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager"/> <tx:annotation-driven /> 
+4
source share
1 answer

As you noticed, declarative transaction management is based on AOP. This means that Spring migrates transaction beans to a transactional proxy server that takes care of starting and completing transactions. This means that the method call must be intercepted by the proxy server in order to be transactional.

It looks like you are calling this method directly from another method of the same bean. In this case, this is a direct call that does not go through the proxy server, which thus cannot start the transaction:

 HTTP request --> controller.someUnknownMethod() --> controller.save() 

The transactional method must be in a separate Spring bean (service) called by the controller. This will make a call through a proxy:

 HTTP request --> controller.someUnknownMethod() --> transactional proxy --> service.save() 

This is described in detail in the documentation .

+9
source

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


All Articles