|
From: <jue...@we...> - 2004-01-30 23:25:52
|
Hmmm, I don't see how Spring's transaction infrastructure could cause =
such behavior... Are you using transaction suspension here (i.e. =
PROPAGATION_REQUIRES_NEW) at all? If not, there's hardly anything that =
Spring could mess up. Better to double-check this, though: I guess the =
debugger is your friend here ;-)
=20
Juergen
=20
________________________________
Von: spr...@li... im Auftrag =
von Colin Sampaleanu
Gesendet: Mi 28.01.2004 18:21
An: spr...@li...; j=FCrgen h=F6ller =
[werk3AT]
Betreff: Re: [Springframework-developer] Reworked transaction =
infrastructure
I've been using the new code for a few days with generaly no issues.
I've come upon a problem now which may or may not have been there
before; it's hard for me to tell, and I can't roll back to the previous
spring version since I need some of the new features elsewhere.
The use case is fairly complex. There is a hierarchical appcontext
(although that is irrelevant), with a number of service beans in there
wrapped transactionally with an interceptor using JTATransactionManager
and with the Hibernate interceptor, via BeanNameAutoProxyCreator. There
is also usage of CMT Session Beans, which get called from Spring
objects, and call to Spring objects. So I have a problem with the
following sequence:
- JMS call to MessageDrivenBean, DispatcherBean
- DispatcherBean gets real POJO service object,
PackagingMessageHandlerImpl, from a context it locates, and delegates to
it. PackagingMessageHandlerImpl is transactionally wrapped by the =
context.
- PackagingMessageHandlerImpl calls out to ApplicationController, a
Session Bean (with CMT)
- ApplicationController gets real POJO service object from context,
ApplicationControllerServiceImpl, and delegates to it.
- ApplicationControllerServiceImpl does some work using some
Hibernate-based Mappers/DAOs.
- ApplicationControllerServiceImpl returns
- transaction manager calls commit, but no commit actually done since
not a new transaction, return continues
- ApplicationController (sessionBean) returns
then I get the following blowup, where JBoss is pretty confused. Looks
like an unknown connection is attempted to be closed, and the real one
isn't (as per the subsequent error about closing connections yourself).
Hard to tell who is at fault here. I will try to dig into this deeper
myself, but if you have any ideas they would be much appreciated:
2004-01-28 10:54:38,934 DEBUG
[org.springframework.transaction.interceptor.TransactionInterceptor]
Invoking commit for transaction on method 'uploadDistribution'
2004-01-28 10:54:38,934 DEBUG
[org.springframework.orm.hibernate.HibernateInterceptor] Not closing
pre-bound Hibernate session after interceptor
2004-01-28 10:54:38,934 INFO=20
[org.jboss.resource.connectionmanager.TxConnectionManager$TxConnectionEve=
ntListener]
throwable from unregister connection
java.lang.IllegalStateException: Trying to return an unknown
connection2! org.jboss.resource.adapter.jdbc.WrappedConnection@5cd34e
at
org.jboss.resource.connectionmanager.CachedConnectionManager.unregisterCo=
nnection(CachedConnectionManager.java:275)
at
org.jboss.resource.connectionmanager.TxConnectionManager$TxConnectionEven=
tListener.connectionClosed(TxConnectionManager.java:550)
at
org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.closeHandle(=
BaseWrapperManagedConnection.java:287)
at
org.jboss.resource.adapter.jdbc.WrappedConnection.close(WrappedConnection=
.java:127)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java=
:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorI=
mpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.jboss.resource.connectionmanager.CachedConnectionManager.closeAll(Cac=
hedConnectionManager.java:375)
at
org.jboss.resource.connectionmanager.CachedConnectionManager.popMetaAware=
Object(CachedConnectionManager.java:199)
at
org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(C=
achedConnectionInterceptor.java:190)
at
org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(Stateles=
sSessionInstanceInterceptor.java:72)
at
org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxIntercep=
tor.java:84)
at
org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorC=
MT.java:267)
at
org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:128)
at
org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java=
:118)
at =
org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191)
at
org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFi=
nderInterceptor.java:122)
at
org.jboss.ejb.StatelessSessionContainer.internalInvoke(StatelessSessionCo=
ntainer.java:331)
at org.jboss.ejb.Container.invoke(Container.java:700)
at sun.reflect.GeneratedMethodAccessor88.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorI=
mpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.jboss.mx.capability.ReflectedMBeanDispatcher.invoke(ReflectedMBeanDis=
patcher.java:284)
at =
org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:546)
at =
org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:101)
at
org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:90=
)
at
org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java=
:46)
at
org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:45)
at
org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSessionIn=
terceptor.java:100)
at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:85)
at $Proxy99.uploadDistribution(Unknown Source)
at
com.whatever.coreserv.services.messaging.PackagingMessageHandlerImpl.onMe=
ssage(PackagingMessageHandlerImpl.java:156)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java=
:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorI=
mpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.springframework.aop.framework.AopProxyUtils.invokeJoinpointUsingRefle=
ction(AopProxyUtils.java:59)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpo=
int(ReflectiveMethodInvocation.java:201)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Refl=
ectiveMethodInvocation.java:176)
at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke=
(TransactionInterceptor.java:156)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Refl=
ectiveMethodInvocation.java:196)
at
org.springframework.orm.hibernate.HibernateInterceptor.invoke(HibernateIn=
terceptor.java:84)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Refl=
ectiveMethodInvocation.java:196)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAop=
Proxy.java:135)
at $Proxy114.onMessage(Unknown Source)
at
com.whatever.coreserv.services.messaging.DispatcherBean.onMessage(Dispatc=
herBean.java:96)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java=
:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorI=
mpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.jboss.ejb.MessageDrivenContainer$ContainerInterceptor.invoke(MessageD=
rivenContainer.java:460)
at
org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(C=
achedConnectionInterceptor.java:186)
at
org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor.invoke(MessageDriv=
enInstanceInterceptor.java:62)
at
org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxIntercep=
tor.java:84)
at
org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorC=
MT.java:240)
at
org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:128)
at
org.jboss.ejb.plugins.RunAsSecurityInterceptor.invoke(RunAsSecurityInterc=
eptor.java:90)
at =
org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191)
at
org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFi=
nderInterceptor.java:122)
at
org.jboss.ejb.MessageDrivenContainer.internalInvoke(MessageDrivenContaine=
r.java:374)
at org.jboss.ejb.Container.invoke(Container.java:700)
at
org.jboss.ejb.plugins.jms.JMSContainerInvoker.invoke(JMSContainerInvoker.=
java:827)
at
org.jboss.ejb.plugins.jms.JMSContainerInvoker$MessageListenerImpl.onMessa=
ge(JMSContainerInvoker.java:1117)
at
org.jboss.jms.asf.StdServerSession.onMessage(StdServerSession.java:256)
at
org.jboss.mq.SpyMessageConsumer.sessionConsumerProcessMessage(SpyMessageC=
onsumer.java:633)
at
org.jboss.mq.SpyMessageConsumer.addMessage(SpyMessageConsumer.java:433)
at org.jboss.mq.SpySession.run(SpySession.java:298)
at org.jboss.jms.asf.StdServerSession.run(StdServerSession.java:180)
at
EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor=
.java:727)
at java.lang.Thread.run(Thread.java:534)
2004-01-28 10:54:39,167 INFO=20
[org.jboss.resource.connectionmanager.CachedConnectionManager]
Successfully closed a connection for you. Please close them yourself:
org.jboss.resource.adapter.jdbc.WrappedConnection@5cd34e
java.lang.Exception: Stack Trace
at
org.jboss.resource.connectionmanager.CachedConnectionManager.closeAll(Cac=
hedConnectionManager.java:376)
at
org.jboss.resource.connectionmanager.CachedConnectionManager.popMetaAware=
Object(CachedConnectionManager.java:199)
at
org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(C=
achedConnectionInterceptor.java:190)
at
org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(Stateles=
sSessionInstanceInterceptor.java:72)
at
org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxIntercep=
tor.java:84)
at
org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorC=
MT.java:267)
at
org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:128)
at
org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java=
:118)
at =
org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191)
at
org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFi=
nderInterceptor.java:122)
at
org.jboss.ejb.StatelessSessionContainer.internalInvoke(StatelessSessionCo=
ntainer.java:331)
at org.jboss.ejb.Container.invoke(Container.java:700)
at sun.reflect.GeneratedMethodAccessor88.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorI=
mpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.jboss.mx.capability.ReflectedMBeanDispatcher.invoke(ReflectedMBeanDis=
patcher.java:284)
at =
org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:546)
at =
org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:101)
at
org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:90=
)
at
org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java=
:46)
at
org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:45)
at
org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSessionIn=
terceptor.java:100)
at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:85)
at $Proxy99.uploadDistribution(Unknown Source)
at
com.whatever.coreserv.services.messaging.PackagingMessageHandlerImpl.onMe=
ssage(PackagingMessageHandlerImpl.java:156)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java=
:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorI=
mpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.springframework.aop.framework.AopProxyUtils.invokeJoinpointUsingRefle=
ction(AopProxyUtils.java:59)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpo=
int(ReflectiveMethodInvocation.java:201)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Refl=
ectiveMethodInvocation.java:176)
at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke=
(TransactionInterceptor.java:156)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Refl=
ectiveMethodInvocation.java:196)
at
org.springframework.orm.hibernate.HibernateInterceptor.invoke(HibernateIn=
terceptor.java:84)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Refl=
ectiveMethodInvocation.java:196)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAop=
Proxy.java:135)
at $Proxy114.onMessage(Unknown Source)
at
com.whatever.coreserv.services.messaging.DispatcherBean.onMessage(Dispatc=
herBean.java:96)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java=
:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorI=
mpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.jboss.ejb.MessageDrivenContainer$ContainerInterceptor.invoke(MessageD=
rivenContainer.java:460)
at
org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(C=
achedConnectionInterceptor.java:186)
at
org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor.invoke(MessageDriv=
enInstanceInterceptor.java:62)
at
org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxIntercep=
tor.java:84)
at
org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorC=
MT.java:240)
at
org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:128)
at
org.jboss.ejb.plugins.RunAsSecurityInterceptor.invoke(RunAsSecurityInterc=
eptor.java:90)
at =
org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191)
at
org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFi=
nderInterceptor.java:122)
at
org.jboss.ejb.MessageDrivenContainer.internalInvoke(MessageDrivenContaine=
r.java:374)
at org.jboss.ejb.Container.invoke(Container.java:700)
at
org.jboss.ejb.plugins.jms.JMSContainerInvoker.invoke(JMSContainerInvoker.=
java:827)
at
org.jboss.ejb.plugins.jms.JMSContainerInvoker$MessageListenerImpl.onMessa=
ge(JMSContainerInvoker.java:1117)
at
org.jboss.jms.asf.StdServerSession.onMessage(StdServerSession.java:256)
at
org.jboss.mq.SpyMessageConsumer.sessionConsumerProcessMessage(SpyMessageC=
onsumer.java:633)
at
org.jboss.mq.SpyMessageConsumer.addMessage(SpyMessageConsumer.java:433)
at org.jboss.mq.SpySession.run(SpySession.java:298)
at org.jboss.jms.asf.StdServerSession.run(StdServerSession.java:180)
at
EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor=
.java:727)
at java.lang.Thread.run(Thread.java:534)
j=FCrgen h=F6ller [werk3AT] wrote:
>Everybody,
>
>I've significantly reworked our transaction infrastructure last week, =
to effectively provide the same support for transaction suspension as =
EJB CMT does. Accordingly, I've introduced propagation behaviors =
"REQUIRES_NEW", "NOT_SUPPORTED", and "NEVER" for all our =
PlatformTransactionManagers. I've committed this yesterday evening, now =
that CVS seems to work again.
>
>JtaTransactionManager needs to access the =
javax.transaction.TransactionManager for transaction suspension; =
unfortunately, the TransactionManager location is not defined by J2EE =
(O/R mappers have a similar problem for cache callbacks in a JTA =
environment). Thus, I've introduced a JtaDialect interface (analogous to =
our JdoDialect), containing "getInternalTransactionManager" and =
"applyIsolationLevel" methods (the latter factored out from =
JtaTransactionManager's template method into this strategy).
>
>The default dialect implementations is JndiLookupJtaDialect, with a =
configurable "templateManagerName" JNDI location (not doing anything =
about the isolation level); its Javadoc states a couple of well-known =
JTA TransactionManager locations in popular application servers. =
Additionally, I've added JotmJtaDialect and WebSphereJtaDialect, which =
both require specific static accessor methods to obtain the JTA =
TransactionManager. I've simply taken the corresponding code from =
Hibernate's TransactionManagerLookups.
>
>There's also a new "jtaDialect" property in LocalSessionFactoryBean, =
allowing to use a Spring-configured JtaDialect for Hibernate's =
TransactionManagerLookup. This avoids double configuration of the =
server-specific lookup strategy. As when providing a DataSource, the =
corresponding Hibernate property will be set implictly when a JtaDialect =
is provided.
>
>I've tested transaction suspension with HibernateTransactionManager and =
DataSourceTransactionManager in Tomcat, Resin, and JBoss; with =
JtaTransactionManager and a corresponding JndiLookupJtaDialect, in Resin =
and JBoss. Works nicely in all cases: I'd be happy if someone else tried =
WebLogic, WebSphere, JOTM, etc (there's nothing to worry about there, =
just validating the TransactionManager lookup strategies).
>
>I've also added a ClobStringType for Hibernate, using a =
LocalSessionFactoryBean-specified LobHandler for mapping Strings to =
CLOBs. You can specify ClobStringType for such fields in your Hibernate =
mappings even if just using CLOBs in certain environments: =
DefaultLobHandler will simply delegate to =
PreparedStatement.setString/ResultSet.getString anyway. On Oracle, =
simply configure OracleLobHandler in your application context - the =
Hibernate mapping file does not have to change.
>
>ClobStringType is particularly useful if you need Strings with more =
than 4000 characters in Oracle mapped to persistent objects via =
Hibernate. You need to use CLOBs for such long texts in Oracle; and due =
to Oracle's peculiar handling of LOBs, you need a special strategy like =
OracleLobHandler. On other databases like MySQL, type "longtext" is =
fine, to be used like normal String values. Our LobHandler abstraction =
allows to turn this into a configuration issue.
>
>If you get the chance, please check this out promptly, as we intend to =
release 1.0 RC1 this weekend!
>
>Juergen
>
>
-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
Springframework-developer mailing list
Spr...@li...
https://lists.sourceforge.net/lists/listinfo/springframework-developer
|
|
From: <jue...@we...> - 2004-01-31 12:51:53
|
Yep. I think it's the most intuitive thing do to: The first =
("upper-most") transaction manager will drive synchronization. After =
all, there's hardly any need to use multiple transaction managers (that =
are active at the same time) now anyway, as transaction suspension =
should cover most of those scenarios.
=20
Juergen
=20
________________________________
Von: spr...@li... im Auftrag =
von Colin Sampaleanu
Gesendet: Sa 31.01.2004 06:26
An: spr...@li...
Betreff: Re: [Springframework-developer] Reworked transaction =
infrastructure
Juergen,
I was looking a bit through the new code (although not enough), and was
wondering a bit about the transaction synchronization. The bug in
DataSourceTransactionManager/DataSourceUtils not allowing even one TM to
have synchronization on if there is more than one TM is of course no
longer there, and if there are multiple TMs and all except one have
synchronization turned off, all will be ok.
However, I am not 100% clear on what happens if more than one has it
turned on (which will be the default when people use multiple TMs and
don't play with the flags). I am not talking about the
RequiresNew/Suspend situation, when it gets taken care of, but rather
with a simple PROPOGATION_REQUIRED. As I read the new code there will
not really be any ill effects, but rather the first TM to be involved
will handle all synchronization, e.g.
private TransactionStatus newTransactionStatus(Object transaction,
boolean newTransaction,
boolean
newSynchronization, boolean debug,
Object
suspendedResources) {
boolean actualNewSynchronization =3D newSynchronization &&
=20
!TransactionSynchronizationManager.isSynchronizationActive();
if (actualNewSynchronization) {
TransactionSynchronizationManager.initSynchronization();
}
return new DefaultTransactionStatus(transaction, newTransaction,
actualNewSynchronization,
debug, suspendedResources);
}
Is this a correct assessment?
Regards,
Colin
j=FCrgen h=F6ller [werk3AT] wrote:
>Everybody,
>
>I've significantly reworked our transaction infrastructure last week, =
to effectively provide the same support for transaction suspension as =
EJB CMT does. Accordingly, I've introduced propagation behaviors =
"REQUIRES_NEW", "NOT_SUPPORTED", and "NEVER" for all our =
PlatformTransactionManagers. I've committed this yesterday evening, now =
that CVS seems to work again.
>
>JtaTransactionManager needs to access the =
javax.transaction.TransactionManager for transaction suspension; =
unfortunately, the TransactionManager location is not defined by J2EE =
(O/R mappers have a similar problem for cache callbacks in a JTA =
environment). Thus, I've introduced a JtaDialect interface (analogous to =
our JdoDialect), containing "getInternalTransactionManager" and =
"applyIsolationLevel" methods (the latter factored out from =
JtaTransactionManager's template method into this strategy).
>
>The default dialect implementations is JndiLookupJtaDialect, with a =
configurable "templateManagerName" JNDI location (not doing anything =
about the isolation level); its Javadoc states a couple of well-known =
JTA TransactionManager locations in popular application servers. =
Additionally, I've added JotmJtaDialect and WebSphereJtaDialect, which =
both require specific static accessor methods to obtain the JTA =
TransactionManager. I've simply taken the corresponding code from =
Hibernate's TransactionManagerLookups.
>
>There's also a new "jtaDialect" property in LocalSessionFactoryBean, =
allowing to use a Spring-configured JtaDialect for Hibernate's =
TransactionManagerLookup. This avoids double configuration of the =
server-specific lookup strategy. As when providing a DataSource, the =
corresponding Hibernate property will be set implictly when a JtaDialect =
is provided.
>
>I've tested transaction suspension with HibernateTransactionManager and =
DataSourceTransactionManager in Tomcat, Resin, and JBoss; with =
JtaTransactionManager and a corresponding JndiLookupJtaDialect, in Resin =
and JBoss. Works nicely in all cases: I'd be happy if someone else tried =
WebLogic, WebSphere, JOTM, etc (there's nothing to worry about there, =
just validating the TransactionManager lookup strategies).
>
>I've also added a ClobStringType for Hibernate, using a =
LocalSessionFactoryBean-specified LobHandler for mapping Strings to =
CLOBs. You can specify ClobStringType for such fields in your Hibernate =
mappings even if just using CLOBs in certain environments: =
DefaultLobHandler will simply delegate to =
PreparedStatement.setString/ResultSet.getString anyway. On Oracle, =
simply configure OracleLobHandler in your application context - the =
Hibernate mapping file does not have to change.
>
>ClobStringType is particularly useful if you need Strings with more =
than 4000 characters in Oracle mapped to persistent objects via =
Hibernate. You need to use CLOBs for such long texts in Oracle; and due =
to Oracle's peculiar handling of LOBs, you need a special strategy like =
OracleLobHandler. On other databases like MySQL, type "longtext" is =
fine, to be used like normal String values. Our LobHandler abstraction =
allows to turn this into a configuration issue.
>
>If you get the chance, please check this out promptly, as we intend to =
release 1.0 RC1 this weekend!
>
>Juergen
>
>
-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
Springframework-developer mailing list
Spr...@li...
https://lists.sourceforge.net/lists/listinfo/springframework-developer
|
|
From: Colin S. <col...@ex...> - 2004-01-31 03:17:56
|
Everything is set as PROPOGATION_REQUIRED. I wouldn't be too surprised if this is a JBoss bug; i.e. its transaction manager is getting confused by the multiple levels of nesting. Hopefully I can get some time in the next week or so to trace though this, although I don't relish the thought of going into the JBoss source... jürgen höller [werk3AT] wrote: >Hmmm, I don't see how Spring's transaction infrastructure could cause such behavior... Are you using transaction suspension here (i.e. PROPAGATION_REQUIRES_NEW) at all? If not, there's hardly anything that Spring could mess up. Better to double-check this, though: I guess the debugger is your friend here ;-) > >Juergen > > >________________________________ > >Von: spr...@li... im Auftrag von Colin Sampaleanu >Gesendet: Mi 28.01.2004 18:21 >An: spr...@li...; jürgen höller [werk3AT] >Betreff: Re: [Springframework-developer] Reworked transaction infrastructure > > > >I've been using the new code for a few days with generaly no issues. >I've come upon a problem now which may or may not have been there >before; it's hard for me to tell, and I can't roll back to the previous >spring version since I need some of the new features elsewhere. > >The use case is fairly complex. There is a hierarchical appcontext >(although that is irrelevant), with a number of service beans in there >wrapped transactionally with an interceptor using JTATransactionManager >and with the Hibernate interceptor, via BeanNameAutoProxyCreator. There >is also usage of CMT Session Beans, which get called from Spring >objects, and call to Spring objects. So I have a problem with the >following sequence: > >- JMS call to MessageDrivenBean, DispatcherBean >- DispatcherBean gets real POJO service object, >PackagingMessageHandlerImpl, from a context it locates, and delegates to >it. PackagingMessageHandlerImpl is transactionally wrapped by the context. >- PackagingMessageHandlerImpl calls out to ApplicationController, a >Session Bean (with CMT) >- ApplicationController gets real POJO service object from context, >ApplicationControllerServiceImpl, and delegates to it. >- ApplicationControllerServiceImpl does some work using some >Hibernate-based Mappers/DAOs. >- ApplicationControllerServiceImpl returns >- transaction manager calls commit, but no commit actually done since >not a new transaction, return continues >- ApplicationController (sessionBean) returns > >then I get the following blowup, where JBoss is pretty confused. Looks >like an unknown connection is attempted to be closed, and the real one >isn't (as per the subsequent error about closing connections yourself). >Hard to tell who is at fault here. I will try to dig into this deeper >myself, but if you have any ideas they would be much appreciated: > >2004-01-28 10:54:38,934 DEBUG >[org.springframework.transaction.interceptor.TransactionInterceptor] >Invoking commit for transaction on method 'uploadDistribution' >2004-01-28 10:54:38,934 DEBUG >[org.springframework.orm.hibernate.HibernateInterceptor] Not closing >pre-bound Hibernate session after interceptor >2004-01-28 10:54:38,934 INFO >[org.jboss.resource.connectionmanager.TxConnectionManager$TxConnectionEventListener] >throwable from unregister connection >java.lang.IllegalStateException: Trying to return an unknown >connection2! org.jboss.resource.adapter.jdbc.WrappedConnection@5cd34e > at >org.jboss.resource.connectionmanager.CachedConnectionManager.unregisterConnection(CachedConnectionManager.java:275) > at >org.jboss.resource.connectionmanager.TxConnectionManager$TxConnectionEventListener.connectionClosed(TxConnectionManager.java:550) > at >org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.closeHandle(BaseWrapperManagedConnection.java:287) > at >org.jboss.resource.adapter.jdbc.WrappedConnection.close(WrappedConnection.java:127) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at >sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at >sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at >org.jboss.resource.connectionmanager.CachedConnectionManager.closeAll(CachedConnectionManager.java:375) > at >org.jboss.resource.connectionmanager.CachedConnectionManager.popMetaAwareObject(CachedConnectionManager.java:199) > at >org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:190) > at >org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:72) > at >org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:84) > at >org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:267) > at >org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:128) > at >org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:118) > at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191) > at >org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122) > at >org.jboss.ejb.StatelessSessionContainer.internalInvoke(StatelessSessionContainer.java:331) > at org.jboss.ejb.Container.invoke(Container.java:700) > at sun.reflect.GeneratedMethodAccessor88.invoke(Unknown Source) > at >sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at >org.jboss.mx.capability.ReflectedMBeanDispatcher.invoke(ReflectedMBeanDispatcher.java:284) > at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:546) > at org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:101) > at >org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:90) > at >org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:46) > at >org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:45) > at >org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSessionInterceptor.java:100) > at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:85) > at $Proxy99.uploadDistribution(Unknown Source) > at >com.whatever.coreserv.services.messaging.PackagingMessageHandlerImpl.onMessage(PackagingMessageHandlerImpl.java:156) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at >sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at >sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at >org.springframework.aop.framework.AopProxyUtils.invokeJoinpointUsingReflection(AopProxyUtils.java:59) > at >org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:201) > at >org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176) > at >org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:156) > at >org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:196) > at >org.springframework.orm.hibernate.HibernateInterceptor.invoke(HibernateInterceptor.java:84) > at >org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:196) > at >org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:135) > at $Proxy114.onMessage(Unknown Source) > at >com.whatever.coreserv.services.messaging.DispatcherBean.onMessage(DispatcherBean.java:96) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at >sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at >sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at >org.jboss.ejb.MessageDrivenContainer$ContainerInterceptor.invoke(MessageDrivenContainer.java:460) > at >org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:186) > at >org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor.invoke(MessageDrivenInstanceInterceptor.java:62) > at >org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:84) > at >org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:240) > at >org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:128) > at >org.jboss.ejb.plugins.RunAsSecurityInterceptor.invoke(RunAsSecurityInterceptor.java:90) > at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191) > at >org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122) > at >org.jboss.ejb.MessageDrivenContainer.internalInvoke(MessageDrivenContainer.java:374) > at org.jboss.ejb.Container.invoke(Container.java:700) > at >org.jboss.ejb.plugins.jms.JMSContainerInvoker.invoke(JMSContainerInvoker.java:827) > at >org.jboss.ejb.plugins.jms.JMSContainerInvoker$MessageListenerImpl.onMessage(JMSContainerInvoker.java:1117) > at >org.jboss.jms.asf.StdServerSession.onMessage(StdServerSession.java:256) > at >org.jboss.mq.SpyMessageConsumer.sessionConsumerProcessMessage(SpyMessageConsumer.java:633) > at >org.jboss.mq.SpyMessageConsumer.addMessage(SpyMessageConsumer.java:433) > at org.jboss.mq.SpySession.run(SpySession.java:298) > at org.jboss.jms.asf.StdServerSession.run(StdServerSession.java:180) > at >EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:727) > at java.lang.Thread.run(Thread.java:534) >2004-01-28 10:54:39,167 INFO >[org.jboss.resource.connectionmanager.CachedConnectionManager] >Successfully closed a connection for you. Please close them yourself: >org.jboss.resource.adapter.jdbc.WrappedConnection@5cd34e >java.lang.Exception: Stack Trace > at >org.jboss.resource.connectionmanager.CachedConnectionManager.closeAll(CachedConnectionManager.java:376) > at >org.jboss.resource.connectionmanager.CachedConnectionManager.popMetaAwareObject(CachedConnectionManager.java:199) > at >org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:190) > at >org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:72) > at >org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:84) > at >org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:267) > at >org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:128) > at >org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:118) > at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191) > at >org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122) > at >org.jboss.ejb.StatelessSessionContainer.internalInvoke(StatelessSessionContainer.java:331) > at org.jboss.ejb.Container.invoke(Container.java:700) > at sun.reflect.GeneratedMethodAccessor88.invoke(Unknown Source) > at >sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at >org.jboss.mx.capability.ReflectedMBeanDispatcher.invoke(ReflectedMBeanDispatcher.java:284) > at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:546) > at org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:101) > at >org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:90) > at >org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:46) > at >org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:45) > at >org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSessionInterceptor.java:100) > at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:85) > at $Proxy99.uploadDistribution(Unknown Source) > at >com.whatever.coreserv.services.messaging.PackagingMessageHandlerImpl.onMessage(PackagingMessageHandlerImpl.java:156) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at >sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at >sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at >org.springframework.aop.framework.AopProxyUtils.invokeJoinpointUsingReflection(AopProxyUtils.java:59) > at >org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:201) > at >org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176) > at >org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:156) > at >org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:196) > at >org.springframework.orm.hibernate.HibernateInterceptor.invoke(HibernateInterceptor.java:84) > at >org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:196) > at >org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:135) > at $Proxy114.onMessage(Unknown Source) > at >com.whatever.coreserv.services.messaging.DispatcherBean.onMessage(DispatcherBean.java:96) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at >sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > at >sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) > at java.lang.reflect.Method.invoke(Method.java:324) > at >org.jboss.ejb.MessageDrivenContainer$ContainerInterceptor.invoke(MessageDrivenContainer.java:460) > at >org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:186) > at >org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor.invoke(MessageDrivenInstanceInterceptor.java:62) > at >org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:84) > at >org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:240) > at >org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:128) > at >org.jboss.ejb.plugins.RunAsSecurityInterceptor.invoke(RunAsSecurityInterceptor.java:90) > at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191) > at >org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122) > at >org.jboss.ejb.MessageDrivenContainer.internalInvoke(MessageDrivenContainer.java:374) > at org.jboss.ejb.Container.invoke(Container.java:700) > at >org.jboss.ejb.plugins.jms.JMSContainerInvoker.invoke(JMSContainerInvoker.java:827) > at >org.jboss.ejb.plugins.jms.JMSContainerInvoker$MessageListenerImpl.onMessage(JMSContainerInvoker.java:1117) > at >org.jboss.jms.asf.StdServerSession.onMessage(StdServerSession.java:256) > at >org.jboss.mq.SpyMessageConsumer.sessionConsumerProcessMessage(SpyMessageConsumer.java:633) > at >org.jboss.mq.SpyMessageConsumer.addMessage(SpyMessageConsumer.java:433) > at org.jboss.mq.SpySession.run(SpySession.java:298) > at org.jboss.jms.asf.StdServerSession.run(StdServerSession.java:180) > at >EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:727) > at java.lang.Thread.run(Thread.java:534) > > > > > > > > >jürgen höller [werk3AT] wrote: > > > >>Everybody, >> >>I've significantly reworked our transaction infrastructure last week, to effectively provide the same support for transaction suspension as EJB CMT does. Accordingly, I've introduced propagation behaviors "REQUIRES_NEW", "NOT_SUPPORTED", and "NEVER" for all our PlatformTransactionManagers. I've committed this yesterday evening, now that CVS seems to work again. >> >>JtaTransactionManager needs to access the javax.transaction.TransactionManager for transaction suspension; unfortunately, the TransactionManager location is not defined by J2EE (O/R mappers have a similar problem for cache callbacks in a JTA environment). Thus, I've introduced a JtaDialect interface (analogous to our JdoDialect), containing "getInternalTransactionManager" and "applyIsolationLevel" methods (the latter factored out from JtaTransactionManager's template method into this strategy). >> >>The default dialect implementations is JndiLookupJtaDialect, with a configurable "templateManagerName" JNDI location (not doing anything about the isolation level); its Javadoc states a couple of well-known JTA TransactionManager locations in popular application servers. Additionally, I've added JotmJtaDialect and WebSphereJtaDialect, which both require specific static accessor methods to obtain the JTA TransactionManager. I've simply taken the corresponding code from Hibernate's TransactionManagerLookups. >> >>There's also a new "jtaDialect" property in LocalSessionFactoryBean, allowing to use a Spring-configured JtaDialect for Hibernate's TransactionManagerLookup. This avoids double configuration of the server-specific lookup strategy. As when providing a DataSource, the corresponding Hibernate property will be set implictly when a JtaDialect is provided. >> >>I've tested transaction suspension with HibernateTransactionManager and DataSourceTransactionManager in Tomcat, Resin, and JBoss; with JtaTransactionManager and a corresponding JndiLookupJtaDialect, in Resin and JBoss. Works nicely in all cases: I'd be happy if someone else tried WebLogic, WebSphere, JOTM, etc (there's nothing to worry about there, just validating the TransactionManager lookup strategies). >> >>I've also added a ClobStringType for Hibernate, using a LocalSessionFactoryBean-specified LobHandler for mapping Strings to CLOBs. You can specify ClobStringType for such fields in your Hibernate mappings even if just using CLOBs in certain environments: DefaultLobHandler will simply delegate to PreparedStatement.setString/ResultSet.getString anyway. On Oracle, simply configure OracleLobHandler in your application context - the Hibernate mapping file does not have to change. >> >>ClobStringType is particularly useful if you need Strings with more than 4000 characters in Oracle mapped to persistent objects via Hibernate. You need to use CLOBs for such long texts in Oracle; and due to Oracle's peculiar handling of LOBs, you need a special strategy like OracleLobHandler. On other databases like MySQL, type "longtext" is fine, to be used like normal String values. Our LobHandler abstraction allows to turn this into a configuration issue. >> >>If you get the chance, please check this out promptly, as we intend to release 1.0 RC1 this weekend! >> >>Juergen >> >> >> |