Java @事务性Spring不创建新事务
在此方面的任何帮助都将不胜感激。Iam使用Spring、Jetty(EclipseJetty插件)。似乎声明性事务管理@Transactional不起作用 确认这在两个方面不起作用: 1.方法调用后,新创建的实体不会刷新到数据库中。 2.TransactionSynchronizationManager.isActualTransactionActive();返回false 注意,下面的方法与@Controller类不同,http请求调用该方法最终会调用该save方法。控制器类不实现任何接口。 实际代码:Java @事务性Spring不创建新事务,java,spring,jetty,spring-transactions,Java,Spring,Jetty,Spring Transactions,在此方面的任何帮助都将不胜感激。Iam使用Spring、Jetty(EclipseJetty插件)。似乎声明性事务管理@Transactional不起作用 确认这在两个方面不起作用: 1.方法调用后,新创建的实体不会刷新到数据库中。 2.TransactionSynchronizationManager.isActualTransactionActive();返回false 注意,下面的方法与@Controller类不同,http请求调用该方法最终会调用该save方法。控制器类不实现任何接口。
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void save(PERule peRule) {
boolean inTransaction = TransactionSynchronizationManager.isActualTransactionActive();
peRuleDAOImpl.persist(peRule);
}
日志输出还确认缺少事务:
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
但是,当我以编程方式定义显式事务边界并提交事务时,实体将被刷新到数据库中。例如:
@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);
}
因此,我定义transactionManager的方式似乎没有问题,因为它可以按照上面的定义注入到对象中
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's 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" />
/WEB-INF/spring/proddatabase.properties
假的
假的
假的
org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory
com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup
servlet上下文:
<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>
上下文配置位置
/WEB-INF/spring/root-context.xml
org.springframework.web.context.ContextLoaderListener
appServlet
org.springframework.web.servlet.DispatcherServlet
上下文配置位置
/WEB-INF/spring/appServlet/servlet-context.xml
1.
appServlet
/
pom.xml相关依赖项:
<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>
cglib
cglibnodep
2.2
org.aspectj
aspectjweaver
1.6.10
org.aspectj
aspectjrt
1.6.10
我还尝试了在我的root-context.xml中驱动tx:annotation的以下变体:
<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 />
正如您所注意到的,声明性事务管理是基于AOP的。这意味着Spring将事务bean包装到事务代理中,该代理负责启动和提交事务。这意味着该方法调用必须被代理截获才能是事务性的 看起来您是直接从同一bean的另一个方法调用此方法。在这种情况下,它是直接调用,不通过代理,因此无法启动事务:
HTTP request --> controller.someUnknownMethod() --> controller.save()
事务方法应该在一个单独的Springbean(服务)中,由控制器调用。这将使调用通过代理进行:
HTTP request --> controller.someUnknownMethod() --> transactional proxy --> service.save()
这将被详细解释。Hi根据建议,我创建了一个服务接口,实现了接口(ServiceImpl),并将DAO(包含事务性保存方法)注入其中。将ServiceImpl注入控制器类,它仍然会产生相同的结果。就好像没有创建代理类一样。Iam使用标准eclipse项目>>清理,然后运行启动服务器的插件。嗨-我从根上下文中删除了transactionManager、atomikosUserTransaction和atomikosTransactionManager。在我的Jetty-Env.xml中配置了它们,启用了JNDI,并且我的root-context.xml中已经有了put ops更正。放入我的根上下文中以自动发现jetty jndi事务管理器