|
From: Colin S. <col...@ex...> - 2004-02-06 23:15:55
|
In fact, unless I am confused, the use of
TransactionInterceptor.currentTransactionStatus().setRollbackOnly()
is problematic. It can not handle the mixed use of a=20
TransactionInterceptor and a contained TransactionTemplate which=20
initiates its own (nested) transaction (due to REQUIRES_NEW being set on=20
its propogation setting).
The user calling
TransactionInterceptor.currentTransactionStatus().setRollbackOnly()
would be setting rollbackonly on the outer transaction status, which was=20
created by the TransactionInterceptor, while in fact he wants to be=20
calling it on the status of the inner transaction he is in...
Colin Sampaleanu wrote:
> Guys, is it worth adding a convenience method for setRollbackOnly, to=20
> TransactionTemplate, something like this? It's a lot more intuitive=20
> than the anonymous class method below.
>
> public void setRollbackOnly() throws TransactionException {
>
> TransactionStatus status =3D=20
> this.transactionManager.getTransaction(this);
> if (status.isNew)
> throw new TransactionUsageException("unable to join existing=20
> transaction. Possible incorrect TransactionTemplate configuration");
> status.setRollbackOnly();
> this.transactionManager.commit(status);
> }
>
> Regards,
> Colin
>
> Colin Sampaleanu wrote:
>
>> This is obviously only going to work if a TransactionInterceptor is=20
>> involved. Alternately, if you want to do this in something like a=20
>> mapper/DAO, and make it work whether or not a TransactionInterceptor=20
>> is involved, you can use TransactionTemplate (in a somewhat=20
>> convoluted fashion). So get a TransactionTemplate in a normal=20
>> fashion, and then do something like this:
>>
>> TransactionTemplate transactionTemplate;
>> ...
>>
>> // now set RollbackOnly via TransactionTemplate; we should join=20
>> the current transaction, and set rollback on that
>> transactionTemplate..execute(new TransactionCallback() {
>> public Object doInTransaction(TransactionStatus status) {
>> status.setRollbackOnly();
>> return null;
>> }
>> });
>>
>> Regards,
>> Colin
>>
>>
>> Rod Johnson wrote:
>>
>>> 1. you don't need to use an unchecked exception, you can set a=20
>>> declarative
>>> rollback rule for the relevant checked exception
>>>
>>> 2. If you do want programmatic rollback you do it like this
>>>
>>> TransactionInterceptor.currentTransactionStatus().setRollbackOnly().
>>>
>>> As in .NET it's static--no need to pass around something like an=20
>>> EJBContext.
>>> currentTransactionStatus() will throw NoTransactionException if you=20
>>> don't
>>> have a tx context. Put the static call in a protected method or=20
>>> strategy
>>> class so you can override it at test time.
>>>
>>> ----- Original Message -----
>>> From: "Sean Radford" <sra...@bl...>
>>> To: <spr...@li...>
>>> Sent: Friday, February 06, 2004 8:04 PM
>>> Subject: [Springframework-user] Retrieving the current transaction
>>>
>>>
>>> Hi all,
>>>
>>>
>>> If one is 'in' a Business Object or DAO class (as defined below), how
>>> does one get the current Transaction in order to set it to rollback? =
(I
>>> don't want to (can't) throw a RuntimeException to get it to happen th=
at
>>> way).
>>>
>>>
>>> <bean id=3D"fooDAO" class=3D"my.FooDAOImpl">
>>> <property name=3D"sessionFactory">
>>> <ref bean=3D"hibernateSessionFactory"/>
>>> </property>
>>> </bean>
>>>
>>> <bean id=3D"fooBoTarget" class=3Dmy.FooBO" singleton=3D"true">
>>> <property name=3D"fooDAO">
>>> <ref bean=3D"fooDAO"/>
>>> </property>
>>> </bean>
>>>
>>> <bean id=3D"eventManager"
>>> class=3D"org.springframework.transaction.interceptor.TransactionProxy=
FactoryBe=20
>>>
>>> an">
>>> <property name=3D"transactionManager">
>>> <ref bean=3D"tm"/>
>>> </property>
>>> <property name=3D"target">
>>> <ref bean=3D"fooBoTarget"/>
>>> </property>
>>> <property name=3D"transactionAttributes">
>>> <props>
>>> <prop key=3D"*">PROPAGATION_REQUIRED</prop>
>>> </props>
>>> </property>
>>> </bean>
>>>
>>>
>>> Regards,
>>>
>>> Sean
>>>
>>> On Fri, 2004-02-06 at 17:21, j=FCrgen h=F6ller [werk3AT] wrote:
>>> =20
>>>
>>>> I'm pleased to announce that Spring 1.0 RC1 will ship with=20
>>>> pre-built JOTM
>>>> =20
>>>
>>>
>>> integration in the form of
>>> org.springframework.transaction.jta.JotmFactoryBean :-)
>>> =20
>>>
>>>> I've just been reworking the new JTA support for the upcoming releas=
e,
>>>> =20
>>>
>>>
>>> turning JtaDialect into FactoryBeans that expose
>>> javax.transaction.TransactionManager. JotmFactoryBean does exactly=20
>>> that too
>>> now; the exposed object implements both UserTransaction and
>>> TransactionManager. In case of an existing JOTM instance, the=20
>>> existing one
>>> will be returned; else, a new local JOTM instance will be created.
>>> =20
>>>
>>>> This can be combined with either JOnAS JNDI DataSources or locally=20
>>>> defined
>>>> =20
>>>
>>>
>>> XAPool DataSources, for example in the local case:
>>> =20
>>>
>>>> <bean id=3D"jotm"
>>>> =20
>>>
>>>
>>> class=3D"org.springframework.transaction.jta.JotmFactoryBean"/>
>>> =20
>>>
>>>> <bean id=3D"transactionManager"
>>>> =20
>>>
>>>
>>> class=3D"org.springframework.transaction.jta.JtaTransactionManager">
>>> =20
>>>
>>>> <property name=3D"userTransaction"><ref local=3D"jotm"/></propert=
y>
>>>> <property name=3D"transactionManager"><ref local=3D"jotm"/></prop=
erty>
>>>> </bean>
>>>>
>>>> <bean id=3D"innerDataSource"
>>>> =20
>>>
>>>
>>> class=3D"org.enhydra.jdbc.standard.StandardXADataSource">
>>> =20
>>>
>>>> <property name=3D"driverName">...</property>
>>>> <property name=3D"url">...</property>
>>>> </bean>
>>>>
>>>> <bean id=3D"dataSource"
>>>> =20
>>>
>>>
>>> class=3D"org.enhydra.jdbc.pool.StandardXAPoolDataSource">
>>> =20
>>>
>>>> <property name=3D"dataSource"><ref=20
>>>> local=3D"innerDataSource"/></property>
>>>> </bean>
>>>>
>>>> Thus, your code can work with "transactionManager" and "dataSource" =
as
>>>> =20
>>>
>>>
>>> usual, just like in the JtaTransactionManager-on-J2EE case - but in a
>>> standalone environment, doing XA transactions via JOTM!
>>> =20
>>>
>>>> Juergen
>>>>
>>>>
>>>> -----Original Message-----
>>>> From: spr...@li...
>>>> [mailto:spr...@li...]On Behalf O=
f
>>>> j=FCrgen h=F6ller [werk3AT]
>>>> Sent: Friday, February 06, 2004 2:27 PM
>>>> To: spr...@li...
>>>> Subject: RE: [Springframework-user] XA Transaction Support
>>>>
>>>>
>>>> Hi Nick,
>>>>
>>>> ObjectWeb's XAPool comes with pre-built DataSource wrappers that are
>>>> =20
>>>
>>>
>>> XA-capable via JOTM. Have a look at the example at
>>> http://xapool.experlog.com/examples.html#xapooldatasource.
>>> =20
>>>
>>>> You shouldn't need to do any enlisting/delisting yourself with=20
>>>> XAPool: You
>>>> =20
>>>
>>>
>>> just need to set up a local JOTM instance and a local XAPool=20
>>> XADataSource,
>>> configured for JOTM.
>>> =20
>>>
>>>> For integration into Spring, a configurer for JOTM could initialize=20
>>>> the
>>>> =20
>>>
>>>
>>> transaction manager on context startup, binding the UserTransaction a=
nd
>>> TransactionManager instances to JNDI. Of course, you need a JNDI
>>> environment; maybe Spring's SimpleNamingContextBuilder is an option.
>>> =20
>>>
>>>> Furthermore, you need a factory for javax.sql.DataSource instances:=20
>>>> You
>>>> =20
>>>
>>>
>>> might need to implement a custom factory here, setting up an XAPool
>>> XADataSource, connecting it to the JNDI-bound TransactionManager, and
>>> wrapping it in a plain DataSource (to be passed to JDBC access code=20
>>> etc).
>>> =20
>>>
>>>> Spring's JtaTransactionManager should work nicely with such a JOTM=20
>>>> setup,
>>>> =20
>>>
>>>
>>> simply accessing the UserTransaction under the given JNDI name. Note=20
>>> that as
>>> of 1.0 RC1, we even support transaction suspension now, and thus all=20
>>> six EJB
>>> CMT propagation codes (including REQUIRES_NEW etc). You just need to=20
>>> set up
>>> a Spring JtaDialect for this.
>>> =20
>>>
>>>> To avoid the need for a JNDI environment (you just need it for the J=
TA
>>>> =20
>>>
>>>
>>> UserTransaction and TransactionManager), you could also implement
>>> FactoryBeans that expose the UserTransaction respectively the
>>> TransactionManager from the JOTM configuration, to be passed as bean
>>> references to JtaTransactionManager and XADataSource FactoryBeans.
>>> =20
>>>
>>>> Of course, I'd be happy to accept code donations to Spring=20
>>>> regarding JOTM
>>>> =20
>>>
>>>
>>> integration :-) Feel free to ask for help if you encounter any issues=
.
>>> =20
>>>
>>>> Juergen
>>>>
>>>>
>>>> -----Original Message-----
>>>> From: spr...@li...
>>>> =20
>>>
>>>
>>> [mailto:spr...@li...]On Behalf=20
>>> Of Nick
>>> Minutello
>>> =20
>>>
>>>> Sent: Friday, February 06, 2004 11:39 AM
>>>> To: spr...@li...
>>>> Subject: [Springframework-user] XA Transaction Support
>>>>
>>>>
>>>> Hi,
>>>> I have to do some out-of-appserver XA transaction management.=20
>>>> (planning on
>>>> =20
>>>
>>>
>>> using JOTM)
>>> =20
>>>
>>>> I was thinking of using an interceptor around the=20
>>>> XAConnectionFactory and
>>>> =20
>>>
>>>
>>> the XADataSource getConnection/close methods to do the enlist/delist
>>> actions.
>>> =20
>>>
>>>> I guess the question is: Is there a better way to do it with=20
>>>> Spring's tx
>>>> =20
>>>
>>>
>>> support?
>>> =20
>>>
>>>> Cheers,
>>>> Nick
>>>
|