我的spring(4.1.1)应用程序部署在JBoss-6.10-final实例上,因此它使用基于容器的事务管理器和数据源。对于消息传递,我使用TIBCO EMS 8.1和XA队列连接工厂设置。 Java版本是1.8.0_20。所有这些都在我的Ubuntu 14.04笔记本电脑上运行。
我需要通过JMS发送请求,然后等待回复。我正在调用的bean将事务传播设置为Propagation.REQUIRED,因此我需要在新事务中发送请求,然后等待回复。这意味着请求在一个单独的bean中发送,事务传播设置为Propagation.REQUIRES_NEW。 它有效,但我收到了JBoss的一个令人担忧的警告:
14-10-02 12:06:12,902警告 [org.jboss.tm.usertx.UserTransactionRegistry](http-0.0.0.0-8080-1) 通知监听器时出错 org.jboss.resource.connectionmanager.CachedConnectionManager@1917b4de userTransactionStarted:java.lang.IllegalStateException:尝试 更改交易TransactionImple< ac,BasicAction: 0:ffff7f000101:126a:542d2010:d8状态:ActionStatus.RUNNING>在 入伍! at org.jboss.resource.connectionmanager.TxConnectionManager $ TxConnectionEventListener.enlist(TxConnectionManager.java:690) 在 org.jboss.resource.connectionmanager.TxConnectionManager.transactionStarted(TxConnectionManager.java:427) 在 org.jboss.resource.connectionmanager.CachedConnectionManager.userTransactionStarted(CachedConnectionManager.java:350) 在 org.jboss.tm.usertx.UserTransactionRegistry.userTransactionStarted(UserTransactionRegistry.java:119) 在 org.jboss.tm.usertx.client.ServerVMClientUserTransaction.begin(ServerVMClientUserTransaction.java:141) 在 org.springframework.transaction.jta.JtaTransactionManager.doJtaBegin(JtaTransactionManager.java:875) 在 org.springframework.transaction.jta.JtaTransactionManager.doBegin(JtaTransactionManager.java:832) 在 org.springframework.transaction.support.AbstractPlatformTransactionManager.handleExistingTransaction(AbstractPlatformTransactionManager.java:425) 在 org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:349) 在 org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:438) 在 org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:261) 在 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) 在com.sun.proxy。$ Proxy234.request(未知来源)at com.izazi.ioriginate.framework.spring.jms.AbstractRequestReply.request(AbstractRequestReply.java:58) 在 com.izazi.ioriginate.service.addressvalidation.AddressValidationServiceImpl.validate(AddressValidationServiceImpl.java:34) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在java.lang.reflect.Method.invoke(Method.java:483)at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 在 org.springframework.transaction.interceptor.TransactionInterceptor $ 1.proceedWithInvocation(TransactionInterceptor.java:98) 在 org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266) 在 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) 在com.sun.proxy。$ Proxy235.validate(未知来源)at com.izazi.ioriginate.services.dwr.AddressValidation.validate(AddressValidation.java:40) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在java.lang.reflect.Method.invoke(Method.java:483)at org.directwebremoting.impl.ExecuteAjaxFilter.doFilter(ExecuteAjaxFilter.java:34) 在 org.directwebremoting.impl.DefaultRemoter $ 1.doFilter(DefaultRemoter.java:428) 在 org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:431) 在 org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:283) 在 org.directwebremoting.servlet.PlainCallHandler.handle(PlainCallHandler.java:52) 在 org.directwebremoting.servlet.UrlProcessor.handle(UrlProcessor.java:101) 在 org.directwebremoting.servlet.DwrServlet.doPost(DwrServlet.java:146) 在javax.servlet.http.HttpServlet.service(HttpServlet.java:754)at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)at at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:324) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) 在 org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) 在 org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) 在 org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) 在 org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) 在 org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) 在 org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) 在 org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:201) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) 在 org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:155) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) 在 org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) 在 org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) 在 org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) 在 org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342) 在 org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) 在 org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 在 org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) 在 org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:274) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) 在 org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:181) 在 org.jboss.modcluster.catalina.CatalinaContext $ RequestListenerValve.event(CatalinaContext.java:285) 在 org.jboss.modcluster.catalina.CatalinaContext $ RequestListenerValve.invoke(CatalinaContext.java:261) 在 org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:88) 在 org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:100) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:159) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 在 org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158) 在 org.apache.catalina.valves.RequestDumperValve.invoke(RequestDumperValve.java:151) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 在 org.jboss.web.tomcat.service.request.ActiveRequestResponseCacheValve.invoke(ActiveRequestResponseCacheValve.java:53) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362) 在 org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) 在 org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process(Http11Protocol.java:654) 在 org.apache.tomcat.util.net.JIoEndpoint $ Worker.run(JIoEndpoint.java:951) 在java.lang.Thread.run(Thread.java:745)
......在EMS方面,我看到了一些XA错误:
@ my_machine:〜/ opt / jboss-6.1.0.Final / bin $ 2014-10-02 10:43:15.801 错误:不存在的消费者的交易:15 connID = 16 sessID = 20 {formatID = 131076 gtrid_length = 29 bqual_length = 28 数据=%00%00%00%00%00%00%00%00%00%00%FF%FF%7F%00%01%01%00%00%12jT-%0D *%00%00%00 AF1%00%00%00%00%00%00%00%00%00%00%FF%FF%7F%00%01%01%00%00%%12jT-%0D *%00%00%00 %B1} 2014-10-02 10:43:15.832错误:处理xa end-transaction时出错 标记为ROLLBACKONLY,例外。 connID = 16 sessID = 20 {formatID = 131076 gtrid_length = 29 bqual_length = 28 数据=%00%00%00%00%00%00%00%00%00%00%FF%FF%7F%00%01%01%00%00%12jT-%0D *%00%00%00 AF1%00%00%00%00%00%00%00%00%00%00%FF%FF%7F%00%01%01%00%00%%12jT-%0D *%00%00%00 %B1}
在查看堆栈跟踪之后,我打开了Spring的AbstractPlatformTransactionManager的源代码,并遇到了以下代码,用于处理REQUIRES_NEW(从第415行开始):
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
if (debugEnabled) {
logger.debug("Suspending current transaction, creating new transaction with name [" +
definition.getName() + "]");
}
SuspendedResourcesHolder suspendedResources = suspend(transaction);
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
catch (Error beginErr) {
resumeAfterBeginException(transaction, suspendedResources, beginErr);
throw beginErr;
}
}
我的问题是:新的交易在哪里开始?
从表面上看,似乎正在使用现有交易,而不是正在启动的新交易 - 请参阅'交易'被传递给doBegin(...)。我也查看了doBegin,并且没有指示要求或创建新事务。这个视图似乎得到了我从JBoss获得的堆栈跟踪和警告......
答案 0 :(得分:3)
很高兴看到我并不孤单被困在这个无洞的洞里......
据我所知,这个警告的深层原因被描述为here(线程结束)
当外部交易被暂停时和新的内部交易 启动,Jboss连接池检索的托管连接 内部交易与外部交易相同 事务,导致抛出IllegalStateException!
并且是由于jboss JCA合同实现的特定行为(Lazy JCA enlistment
)。
A defect has been opened on spring side,标记为"无法修复"但它们提供了一种解决方法配置:
典型的解决方案是使用Spring TransactionAwareDataSourceProxy并切换 " reobtainTransactionalConnections"标记为" true"有
玩得开心!