Spring 休眠 "You cannot commit during a managed transaction!"
Spring Hibernate "You cannot commit during a managed transaction!"
将我的应用程序从 JSF 1.2 升级到 JSF 2.1 后,我在尝试登录时遇到以下 Spring Hibernate 异常:
DEBUG,[interceptor.ExceptionInterceptor][],org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: commit failed
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:472)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:392)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at myapp.aop.interceptor.MethodExceptionInterceptor.invoke(MethodExceptionInterceptor.java:21)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at myapp.aop.interceptor.SessionActivityInterceptor.invoke(SessionActivityInterceptor.java:47)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy121.endSession(Unknown Source)
at myapp.web.action.connection.ConnectionBean.connect(ConnectionBean.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:32)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
at myapp.web.interceptor.ExceptionInterceptor.aroundInvoke(ExceptionInterceptor.java:42)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:28)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
at org.jboss.seam.core.SynchronizationInterceptor.aroundInvoke(SynchronizationInterceptor.java:35)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:186)
at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:104)
at myapp.web.action.connection.ConnectionBean_$$_javassist_seam_2.connect(ConnectionBean_$$_javassist_seam_2.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:335)
at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:348)
at org.jboss.el.parser.AstPropertySuffix.invoke(AstPropertySuffix.java:58)
at org.jboss.el.parser.AstValue.invoke(AstValue.java:96)
at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at org.apache.myfaces.trinidad.component.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:46)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:101)
at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:190)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:786)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1251)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._invokeApplication(LifecycleImpl.java:1074)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:402)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:225)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:105)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:502)
at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:60)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:502)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:327)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:229)
at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at myapp.web.filter.SessionActivityFilter.doFilter(SessionActivityFilter.java:67)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:389)
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:145)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:336)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:920)
at java.lang.Thread.run(Thread.java:724)
Caused by: org.hibernate.TransactionException: commit failed
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:185)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:468)
... 93 more
Caused by: org.hibernate.TransactionException: unable to commit against JDBC connection
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doCommit(JdbcTransaction.java:116)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:178)
... 94 more
Caused by: java.sql.SQLException: You cannot commit during a managed transaction!
at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.jdbcCommit(BaseWrapperManagedConnection.java:1052)
at org.jboss.jca.adapters.jdbc.WrappedConnection.commit(WrappedConnection.java:757)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doCommit(JdbcTransaction.java:112)
... 95 more
这是我的 spring beans 配置:
<bean id="parentSessionFactory" abstract="true">
<property name="dataSource">
<ref bean="myDS" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.connection.driver_class">
org.h2.Driver
</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_structured_cache">true</prop>
</props>
</property>
</bean>
<bean id="myDS"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:/myDS" />
</bean>
<bean id="sessionFactory" parent="parentSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation">
<value>
classpath:model/hibernate.cfg.xml
</value>
</property>
<property name="hibernateProperties">
<props merge="true">
<prop key="hibernate.dialect">
org.hibernate.dialect.H2Dialect
</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<!-- the transactional advice (i.e. what 'happens'; see the <aop:advisor/> bean below) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- all methods starting with 'get' are read-only -->
<tx:method name="get*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="list*" read-only="true" />
<tx:method name="read*" read-only="true" />
<tx:method name="save*" read-only="false" isolation="READ_COMMITTED"/>
<tx:method name="remove*" read-only="false" isolation="READ_COMMITTED"/>
<tx:method name="refresh*" read-only="false" isolation="READ_COMMITTED"/>
<tx:method name="delete*" read-only="false" isolation="READ_COMMITTED"/>
<!-- other methods use the default transaction settings (see below) -->
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- ensure that the above transactional advice runs for any execution
of an operation defined by the *Service interface -->
<aop:config>
<aop:pointcut id="serviceOperation"
expression="execution(* services..*Service*.*(..))" />
<aop:pointcut id="daoOperation"
expression="execution(* dao..*Dao.*(..))" />
<aop:advisor advice-ref="sessionActivityInterceptor"
pointcut-ref="serviceOperation" />
<aop:advisor advice-ref="exceptionInterceptor"
pointcut-ref="serviceOperation" /> -->
<aop:advisor advice-ref="txAdvice"
pointcut-ref="serviceOperation" />
<aop:advisor advice-ref="txAdvice"
pointcut-ref="daoOperation" />
</aop:config>
这里是 hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
<!-- <property name="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</property> -->
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- Several mapping classes here -->
</session-factory>
</hibernate-configuration>
@Transactional
注释仅在我的应用程序和单元测试中的一个方法中使用,但未用于应用程序的登录部分。
进一步调查我的异常,我看到在 BaseWrapperManagedConnection
中从 ironjacamar-jdbc-1.0.17
抛出异常的代码:
/**
* JDBC commit
* @exception SQLException Thrown if an error occurs
*/
void jdbcCommit() throws SQLException
{
synchronized (stateLock)
{
if (inManagedTransaction)
throw new SQLException("You cannot commit during a managed transaction!");
if (jdbcAutoCommit)
throw new SQLException("You cannot commit with autocommit set!");
}
con.commit();
if (mcf.isJTA().booleanValue())
{
if (inLocalTransaction.getAndSet(false))
{
Collection<ConnectionEventListener> copy = null;
synchronized (cels)
{
copy = new ArrayList<ConnectionEventListener>(cels);
}
ConnectionEvent ce = new ConnectionEvent(this, ConnectionEvent.LOCAL_TRANSACTION_COMMITTED);
for (Iterator<ConnectionEventListener> i = copy.iterator(); i.hasNext();)
{
ConnectionEventListener cel = i.next();
try
{
cel.localTransactionCommitted(ce);
}
catch (Throwable t)
{
if (trace)
getLog().trace("Error notifying of connection committed for listener: " + cel, t);
}
}
}
}
}
变量 inManagedTransaction
在 LocalManagedConnection
begin 方法中设置为 true from ironjacamar-jdbc-1.0.17
:
/**
* {@inheritDoc}
*/
public void begin() throws ResourceException
{
lock();
try
{
synchronized (stateLock)
{
if (!inManagedTransaction)
{
try
{
if (underlyingAutoCommit)
{
underlyingAutoCommit = false;
con.setAutoCommit(false);
}
checkState();
inManagedTransaction = true;
}
catch (SQLException e)
{
checkException(e);
}
}
else
throw new ResourceException("Trying to begin a nested local tx");
}
}
finally
{
unlock();
}
}
唯一将此 inManagedTransaction
设置为 false 的地方是在 LocalManagedConnection
commit()
或 rollback()
方法中:
/**
* {@inheritDoc}
*/
public void commit() throws ResourceException
{
lock();
try
{
synchronized (stateLock)
{
if (inManagedTransaction)
inManagedTransaction = false;
}
try
{
con.commit();
}
catch (SQLException e)
{
checkException(e);
}
}
finally
{
unlock();
}
}
/**
* {@inheritDoc}
*/
public void rollback() throws ResourceException
{
lock();
try
{
synchronized (stateLock)
{
if (inManagedTransaction)
inManagedTransaction = false;
}
try
{
con.rollback();
}
catch (SQLException e)
{
try
{
checkException(e);
}
catch (Exception e2)
{
// Ignore
}
}
}
finally
{
unlock();
}
}
我有两个 ManagedConnection 一个是 BaseWrapperManagedConnection
另一个是 LocalManagedConnection
并且我正在经历他们的两种提交方法是否正常?
我还读到 JBoss 也可以处理事务(容器管理的事务)。是否有可能 Spring 和 JBoss 都试图处理我的会话和事务?
我正在使用 Hibernate 4.2 和 Spring 3.2.0。
其中大部分是经典配置,就像在网络上的许多教程中找到的一样,没什么特别的。使用此配置的应用程序使用 JSF 1.2 运行。
感谢您的任何建议,提示。
您可能在 JBoss 中配置了 JTA 数据源,这是一个托管事务资源,然后您使用的是非 JTA HibernateTransactionManager
。
要修复它,您有两种选择:
- 您可以使用 RESOURCE_LOCAL 数据源并通过 JNDI 提供它
- 您保留 JTA 数据源并将 Hibernate 配置为使用 Spring JtaTransactionManager with the actual Arjuna Transaction Manager
如果您的数据源使用 jta,则不能调用 transaction.begin 也不能提交那些由容器调用的事务划分。
如果您的数据源使用 RESOURCE_LOCAL,您必须划分所有事务,即使是只读事务。
将我的应用程序从 JSF 1.2 升级到 JSF 2.1 后,我在尝试登录时遇到以下 Spring Hibernate 异常:
DEBUG,[interceptor.ExceptionInterceptor][],org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: commit failed
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:472)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:392)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at myapp.aop.interceptor.MethodExceptionInterceptor.invoke(MethodExceptionInterceptor.java:21)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at myapp.aop.interceptor.SessionActivityInterceptor.invoke(SessionActivityInterceptor.java:47)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy121.endSession(Unknown Source)
at myapp.web.action.connection.ConnectionBean.connect(ConnectionBean.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:32)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
at myapp.web.interceptor.ExceptionInterceptor.aroundInvoke(ExceptionInterceptor.java:42)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:28)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
at org.jboss.seam.core.SynchronizationInterceptor.aroundInvoke(SynchronizationInterceptor.java:35)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:186)
at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:104)
at myapp.web.action.connection.ConnectionBean_$$_javassist_seam_2.connect(ConnectionBean_$$_javassist_seam_2.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:335)
at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:348)
at org.jboss.el.parser.AstPropertySuffix.invoke(AstPropertySuffix.java:58)
at org.jboss.el.parser.AstValue.invoke(AstValue.java:96)
at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at org.apache.myfaces.trinidad.component.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:46)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:101)
at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:190)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:786)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1251)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._invokeApplication(LifecycleImpl.java:1074)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:402)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:225)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:105)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:502)
at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:60)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:502)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:327)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:229)
at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at myapp.web.filter.SessionActivityFilter.doFilter(SessionActivityFilter.java:67)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:389)
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:145)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:336)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:920)
at java.lang.Thread.run(Thread.java:724)
Caused by: org.hibernate.TransactionException: commit failed
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:185)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:468)
... 93 more
Caused by: org.hibernate.TransactionException: unable to commit against JDBC connection
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doCommit(JdbcTransaction.java:116)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:178)
... 94 more
Caused by: java.sql.SQLException: You cannot commit during a managed transaction!
at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.jdbcCommit(BaseWrapperManagedConnection.java:1052)
at org.jboss.jca.adapters.jdbc.WrappedConnection.commit(WrappedConnection.java:757)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doCommit(JdbcTransaction.java:112)
... 95 more
这是我的 spring beans 配置:
<bean id="parentSessionFactory" abstract="true">
<property name="dataSource">
<ref bean="myDS" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.connection.driver_class">
org.h2.Driver
</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_structured_cache">true</prop>
</props>
</property>
</bean>
<bean id="myDS"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:/myDS" />
</bean>
<bean id="sessionFactory" parent="parentSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation">
<value>
classpath:model/hibernate.cfg.xml
</value>
</property>
<property name="hibernateProperties">
<props merge="true">
<prop key="hibernate.dialect">
org.hibernate.dialect.H2Dialect
</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<!-- the transactional advice (i.e. what 'happens'; see the <aop:advisor/> bean below) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- all methods starting with 'get' are read-only -->
<tx:method name="get*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="list*" read-only="true" />
<tx:method name="read*" read-only="true" />
<tx:method name="save*" read-only="false" isolation="READ_COMMITTED"/>
<tx:method name="remove*" read-only="false" isolation="READ_COMMITTED"/>
<tx:method name="refresh*" read-only="false" isolation="READ_COMMITTED"/>
<tx:method name="delete*" read-only="false" isolation="READ_COMMITTED"/>
<!-- other methods use the default transaction settings (see below) -->
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- ensure that the above transactional advice runs for any execution
of an operation defined by the *Service interface -->
<aop:config>
<aop:pointcut id="serviceOperation"
expression="execution(* services..*Service*.*(..))" />
<aop:pointcut id="daoOperation"
expression="execution(* dao..*Dao.*(..))" />
<aop:advisor advice-ref="sessionActivityInterceptor"
pointcut-ref="serviceOperation" />
<aop:advisor advice-ref="exceptionInterceptor"
pointcut-ref="serviceOperation" /> -->
<aop:advisor advice-ref="txAdvice"
pointcut-ref="serviceOperation" />
<aop:advisor advice-ref="txAdvice"
pointcut-ref="daoOperation" />
</aop:config>
这里是 hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
<!-- <property name="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</property> -->
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- Several mapping classes here -->
</session-factory>
</hibernate-configuration>
@Transactional
注释仅在我的应用程序和单元测试中的一个方法中使用,但未用于应用程序的登录部分。
进一步调查我的异常,我看到在 BaseWrapperManagedConnection
中从 ironjacamar-jdbc-1.0.17
抛出异常的代码:
/**
* JDBC commit
* @exception SQLException Thrown if an error occurs
*/
void jdbcCommit() throws SQLException
{
synchronized (stateLock)
{
if (inManagedTransaction)
throw new SQLException("You cannot commit during a managed transaction!");
if (jdbcAutoCommit)
throw new SQLException("You cannot commit with autocommit set!");
}
con.commit();
if (mcf.isJTA().booleanValue())
{
if (inLocalTransaction.getAndSet(false))
{
Collection<ConnectionEventListener> copy = null;
synchronized (cels)
{
copy = new ArrayList<ConnectionEventListener>(cels);
}
ConnectionEvent ce = new ConnectionEvent(this, ConnectionEvent.LOCAL_TRANSACTION_COMMITTED);
for (Iterator<ConnectionEventListener> i = copy.iterator(); i.hasNext();)
{
ConnectionEventListener cel = i.next();
try
{
cel.localTransactionCommitted(ce);
}
catch (Throwable t)
{
if (trace)
getLog().trace("Error notifying of connection committed for listener: " + cel, t);
}
}
}
}
}
变量 inManagedTransaction
在 LocalManagedConnection
begin 方法中设置为 true from ironjacamar-jdbc-1.0.17
:
/**
* {@inheritDoc}
*/
public void begin() throws ResourceException
{
lock();
try
{
synchronized (stateLock)
{
if (!inManagedTransaction)
{
try
{
if (underlyingAutoCommit)
{
underlyingAutoCommit = false;
con.setAutoCommit(false);
}
checkState();
inManagedTransaction = true;
}
catch (SQLException e)
{
checkException(e);
}
}
else
throw new ResourceException("Trying to begin a nested local tx");
}
}
finally
{
unlock();
}
}
唯一将此 inManagedTransaction
设置为 false 的地方是在 LocalManagedConnection
commit()
或 rollback()
方法中:
/**
* {@inheritDoc}
*/
public void commit() throws ResourceException
{
lock();
try
{
synchronized (stateLock)
{
if (inManagedTransaction)
inManagedTransaction = false;
}
try
{
con.commit();
}
catch (SQLException e)
{
checkException(e);
}
}
finally
{
unlock();
}
}
/**
* {@inheritDoc}
*/
public void rollback() throws ResourceException
{
lock();
try
{
synchronized (stateLock)
{
if (inManagedTransaction)
inManagedTransaction = false;
}
try
{
con.rollback();
}
catch (SQLException e)
{
try
{
checkException(e);
}
catch (Exception e2)
{
// Ignore
}
}
}
finally
{
unlock();
}
}
我有两个 ManagedConnection 一个是 BaseWrapperManagedConnection
另一个是 LocalManagedConnection
并且我正在经历他们的两种提交方法是否正常?
我还读到 JBoss 也可以处理事务(容器管理的事务)。是否有可能 Spring 和 JBoss 都试图处理我的会话和事务?
我正在使用 Hibernate 4.2 和 Spring 3.2.0。 其中大部分是经典配置,就像在网络上的许多教程中找到的一样,没什么特别的。使用此配置的应用程序使用 JSF 1.2 运行。 感谢您的任何建议,提示。
您可能在 JBoss 中配置了 JTA 数据源,这是一个托管事务资源,然后您使用的是非 JTA HibernateTransactionManager
。
要修复它,您有两种选择:
- 您可以使用 RESOURCE_LOCAL 数据源并通过 JNDI 提供它
- 您保留 JTA 数据源并将 Hibernate 配置为使用 Spring JtaTransactionManager with the actual Arjuna Transaction Manager
如果您的数据源使用 jta,则不能调用 transaction.begin 也不能提交那些由容器调用的事务划分。 如果您的数据源使用 RESOURCE_LOCAL,您必须划分所有事务,即使是只读事务。