Cannot be used outside XA transaction scope

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Cannot be used outside XA transaction scope

Tran Duy Tung
Dear all!

I'm trying to run a simple program that is integration of Spring and Bitronix 2.0. My RDBMS is PostgreSql. I modified the template at  http://docs.codehaus.org/display/BTM/Spring+Framework13 to substitute Derby DB because I used PostgreSql. But when I try to run the code that insert data to 2 schemas in PostgreSql. It threw out exception like this:

log4j:WARN No appenders could be found for logger (org.springframework.context.support.FileSystemXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
Jul 10, 2010 10:30:31 AM bitronix.tm.BitronixTransactionManager logVersion
INFO: Bitronix Transaction Manager version 2.0.0
Jul 10, 2010 10:30:31 AM bitronix.tm.Configuration buildServerIdArray
INFO: JVM unique ID: <spring-btm>
Jul 10, 2010 10:30:31 AM bitronix.tm.journal.DiskJournal open
WARNING: active log file is unclean, did you call BitronixTransactionManager.shutdown() at the end of the last run?
Jul 10, 2010 10:30:31 AM bitronix.tm.recovery.Recoverer run
INFO: recovery committed 0 dangling transaction(s) and rolled back 0 aborted transaction(s) on 2 resource(s) [jdbc/ds2, jdbc/ds1] (restricted to serverId 'spring-btm') ---->>>// Does this mean no transaction branch can join the global transaction?
Exception in thread "main" org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [INSERT INTO person(id, name) VALUES(?, ?)]; SQL state [null]; error code [0]; error enlisting a JdbcConnectionHandle of a JdbcPooledConnection from datasource jdbc/ds2 in state ACCESSIBLE with usage count 1 wrapping org.postgresql.xa.PGXAConnection@19fe451 on Pooled connection wrapping physical connection org.postgresql.jdbc3.Jdbc3Connection@46b90a; nested exception is java.sql.SQLException: error enlisting a JdbcConnectionHandle of a JdbcPooledConnection from datasource jdbc/ds2 in state ACCESSIBLE with usage count 1 wrapping org.postgresql.xa.PGXAConnection@19fe451 on Pooled connection wrapping physical connection org.postgresql.jdbc3.Jdbc3Connection@46b90a
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:607)
        at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:792)
        at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:850)
        at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:858)
        at org.springframework.jdbc.core.simple.SimpleJdbcTemplate.update(SimpleJdbcTemplate.java:237)
        at discoverybitronix.examples.dao.impl.SimplePersonDaoImpl1.save(SimplePersonDaoImpl1.java:19)
        at discoverybitronix.examples.Program.main(Program.java:18)
Caused by: java.sql.SQLException: error enlisting a JdbcConnectionHandle of a JdbcPooledConnection from datasource jdbc/ds2 in state ACCESSIBLE with usage count 1 wrapping org.postgresql.xa.PGXAConnection@19fe451 on Pooled connection wrapping physical connection org.postgresql.jdbc3.Jdbc3Connection@46b90a
        at bitronix.tm.resource.jdbc.JdbcConnectionHandle.enlistResource(JdbcConnectionHandle.java:67)
        at bitronix.tm.resource.jdbc.JdbcConnectionHandle.prepareStatement(JdbcConnectionHandle.java:224)
        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:597)
        at bitronix.tm.resource.jdbc.BaseProxyHandlerClass.invoke(BaseProxyHandlerClass.java:44)
        at $Proxy2.prepareStatement(Unknown Source)
        at org.springframework.jdbc.core.JdbcTemplate$SimplePreparedStatementCreator.createPreparedStatement(JdbcTemplate.java:1322)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:585)
        ... 6 more
Caused by: bitronix.tm.internal.BitronixSystemException: resource 'jdbc/ds2' cannot be used outside XA transaction scope. Set allowLocalTransactions to true if you want to allow this and you know your resource supports this.
        at bitronix.tm.resource.common.TransactionContextHelper.enlistInCurrentTransaction(TransactionContextHelper.java:60)
        at bitronix.tm.resource.jdbc.JdbcConnectionHandle.enlistResource(JdbcConnectionHandle.java:65)
        ... 15 more


And this is my Spring's config

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
       
       
        <bean id="dataSource1" class="bitronix.tm.resource.jdbc.PoolingDataSource"
                init-method="init" destroy-method="close">
                <property name="className"
                        value="org.postgresql.xa.PGXADataSource" />
  <property name="uniqueName" value="jdbc/ds1" /> 
                <property name="minPoolSize" value="2" />
                <property name="maxPoolSize" value="32" />
  <property name="useTmJoin" value="true" />
  <property name="allowLocalTransactions" value="false" /> 

                <property name="driverProperties">
                        <props>
                                <prop key="serverName">localhost</prop>
                                <prop key="databaseName">schema1</prop>
                                <prop key="portNumber">5432</prop>
                                <prop key="user">postgres</prop>
                                <prop key="password">johnlennon</prop>
                        </props>
                </property>
        </bean>

       
        <bean id="dataSource2" class="bitronix.tm.resource.jdbc.PoolingDataSource"
                init-method="init" destroy-method="close">
                <property name="className"
                        value="org.postgresql.xa.PGXADataSource" />
                <property name="uniqueName" value="jdbc/ds2" />
                <property name="minPoolSize" value="2" />
                <property name="maxPoolSize" value="32" />
                <property name="useTmJoin" value="true" />
                <property name="allowLocalTransactions" value="false" />

                <property name="driverProperties">
                        <props>
                                <prop key="serverName">localhost</prop>
                                <prop key="databaseName">schema2</prop>
                                <prop key="portNumber">5432</prop>
                                <prop key="user">postgres</prop>
                                <prop key="password">johnlennon</prop>
                        </props>
                </property>
        </bean>

       
        <bean id="btmConfig" factory-method="getConfiguration"
                class="bitronix.tm.TransactionManagerServices">
                <property name="serverId" value="spring-btm" />
        </bean>

       
        <bean id="bitronixTransactionManager" factory-method="getTransactionManager"
                class="bitronix.tm.TransactionManagerServices"
                depends-on="btmConfig"
                destroy-method="shutdown" />

       
        <bean id="jtaTransactionManager"
                class="org.springframework.transaction.jta.JtaTransactionManager">
                <property name="transactionManager" ref="bitronixTransactionManager" />
                <property name="userTransaction" ref="bitronixTransactionManager" />
        </bean>

       
        <bean id="baseTransactionProxy"
                class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
                abstract="true">
                <property name="transactionManager" ref="jtaTransactionManager" />
                <property name="transactionAttributes">
                        <props>
                                <prop key="save">PROPAGATION_REQUIRED, -Exception</prop>
                        </props>
                </property>
        </bean>

       
        <bean id="simplePersonDaoImpl1"
                class="discoverybitronix.examples.dao.impl.SimplePersonDaoImpl1">
                <property name="dataSource" ref="dataSource1" />
        </bean>

        <bean id="simplePersonDaoImpl2"
                class="discoverybitronix.examples.dao.impl.SimplePersonDaoImpl1">
                <property name="dataSource" ref="dataSource2" />
        </bean>

       
        <bean id="proxy1" parent="baseTransactionProxy">
                <property name="target" ref="simplePersonDaoImpl1" />
        </bean> 
        <bean id="proxy2" parent="baseTransactionProxy">
                <property name="target" ref="simplePersonDaoImpl2" />
        </bean>

</beans>

Please help me handle this prob.

Thanks!
Reply | Threaded
Open this post in threaded view
|

Re: Cannot be used outside XA transaction scope

snicoll
Hi,

Your jdbcTemplate has no transaction when it runs. Does
SimplePersonDaoImpl1#update creates the table ?

Anyway, your code is not within a transaction when it's looking up a
connection. By default, this is not allowed and it's probably what you
expect. You need to start a transaction by, for instance, adding a
@Transactional on your public save method and enable declarative
transaction in Spring (<tx:annotation-config/>).

Note that in the future if you are using something like hibernate, you
need to switch allowLocalTransactions to true as Hibernate will update
your schema without a transaction on startup (that's exactly what
you're having here, except it's your code and  you can fix it).

HTH,
Stéphane



On Sat, Jul 10, 2010 at 5:41 AM, Tran Duy Tung <[hidden email]> wrote:

>
> Dear all!
>
> I'm trying to run a simple program that is integration of Spring and
> Bitronix 2.0. My RDBMS is PostgreSql. I modified the template at
> http://docs.codehaus.org/display/BTM/Spring+Framework13
> http://docs.codehaus.org/display/BTM/Spring+Framework13  to substitute Derby
> DB because I used PostgreSql. But when I try to run the code that insert
> data to 2 schemas in PostgreSql. It threw out exception like this:
>
> log4j:WARN No appenders could be found for logger
> (org.springframework.context.support.FileSystemXmlApplicationContext).
> log4j:WARN Please initialize the log4j system properly.
> Jul 10, 2010 10:30:31 AM bitronix.tm.BitronixTransactionManager logVersion
> INFO: Bitronix Transaction Manager version 2.0.0
> Jul 10, 2010 10:30:31 AM bitronix.tm.Configuration buildServerIdArray
> INFO: JVM unique ID: <spring-btm>
> Jul 10, 2010 10:30:31 AM bitronix.tm.journal.DiskJournal open
> WARNING: active log file is unclean, did you call
> BitronixTransactionManager.shutdown() at the end of the last run?
> Jul 10, 2010 10:30:31 AM bitronix.tm.recovery.Recoverer run
> INFO: recovery committed 0 dangling transaction(s) and rolled back 0 aborted
> transaction(s) on 2 resource(s) [jdbc/ds2, jdbc/ds1] (restricted to serverId
> 'spring-btm') ---->>>// Does this mean no transaction branch can join the
> global transaction?
> Exception in thread "main"
> org.springframework.jdbc.UncategorizedSQLException:
> PreparedStatementCallback; uncategorized SQLException for SQL [INSERT INTO
> person(id, name) VALUES(?, ?)]; SQL state [null]; error code [0]; error
> enlisting a JdbcConnectionHandle of a JdbcPooledConnection from datasource
> jdbc/ds2 in state ACCESSIBLE with usage count 1 wrapping
> org.postgresql.xa.PGXAConnection@19fe451 on Pooled connection wrapping
> physical connection org.postgresql.jdbc3.Jdbc3Connection@46b90a; nested
> exception is java.sql.SQLException: error enlisting a JdbcConnectionHandle
> of a JdbcPooledConnection from datasource jdbc/ds2 in state ACCESSIBLE with
> usage count 1 wrapping org.postgresql.xa.PGXAConnection@19fe451 on Pooled
> connection wrapping physical connection
> org.postgresql.jdbc3.Jdbc3Connection@46b90a
>        at
> org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
>        at
> org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
>        at
> org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
>        at
> org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:607)
>        at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:792)
>        at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:850)
>        at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:858)
>        at
> org.springframework.jdbc.core.simple.SimpleJdbcTemplate.update(SimpleJdbcTemplate.java:237)
>        at
> discoverybitronix.examples.dao.impl.SimplePersonDaoImpl1.save(SimplePersonDaoImpl1.java:19)
>        at discoverybitronix.examples.Program.main(Program.java:18)
> Caused by: java.sql.SQLException: error enlisting a JdbcConnectionHandle of
> a JdbcPooledConnection from datasource jdbc/ds2 in state ACCESSIBLE with
> usage count 1 wrapping org.postgresql.xa.PGXAConnection@19fe451 on Pooled
> connection wrapping physical connection
> org.postgresql.jdbc3.Jdbc3Connection@46b90a
>        at
> bitronix.tm.resource.jdbc.JdbcConnectionHandle.enlistResource(JdbcConnectionHandle.java:67)
>        at
> bitronix.tm.resource.jdbc.JdbcConnectionHandle.prepareStatement(JdbcConnectionHandle.java:224)
>        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:597)
>        at
> bitronix.tm.resource.jdbc.BaseProxyHandlerClass.invoke(BaseProxyHandlerClass.java:44)
>        at $Proxy2.prepareStatement(Unknown Source)
>        at
> org.springframework.jdbc.core.JdbcTemplate$SimplePreparedStatementCreator.createPreparedStatement(JdbcTemplate.java:1322)
>        at
> org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:585)
>        ... 6 more
> Caused by: bitronix.tm.internal.BitronixSystemException: resource 'jdbc/ds2'
> cannot be used outside XA transaction scope. Set allowLocalTransactions to
> true if you want to allow this and you know your resource supports this.
>        at
> bitronix.tm.resource.common.TransactionContextHelper.enlistInCurrentTransaction(TransactionContextHelper.java:60)
>        at
> bitronix.tm.resource.jdbc.JdbcConnectionHandle.enlistResource(JdbcConnectionHandle.java:65)
>        ... 15 more
>
>
> And this is my Spring's config
>
> <?xml version="1.0" encoding="UTF-8"?>
> <beans xmlns="http://www.springframework.org/schema/beans"
>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xmlns:aop="http://www.springframework.org/schema/aop"
>        xsi:schemaLocation="http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans.xsd
>                http://www.springframework.org/schema/aop
> http://www.springframework.org/schema/aop/spring-aop.xsd">
>
>        <!-- PostgreSql Data Source 1 -->
>        <bean id="dataSource1" class="bitronix.tm.resource.jdbc.PoolingDataSource"
>                init-method="init" destroy-method="close">
>                <property name="className"
>                        value="org.postgresql.xa.PGXADataSource" />
>                <property name="uniqueName" value="jdbc/ds1" />
>                <property name="minPoolSize" value="2" />
>                <property name="maxPoolSize" value="32" />
>                <property name="useTmJoin" value="true" />
>                <property name="allowLocalTransactions" value="false" />
>                <property name="driverProperties">
>                        <props>
>                                <prop key="serverName">localhost</prop>
>                                <prop key="databaseName">schema1</prop>
>                                <prop key="portNumber">5432</prop>
>                                <prop key="user">postgres</prop>
>                                <prop key="password">johnlennon</prop>
>                        </props>
>                </property>
>        </bean>
>
>        <!-- PostgreSql Data Source 2 -->
>        <bean id="dataSource2" class="bitronix.tm.resource.jdbc.PoolingDataSource"
>                init-method="init" destroy-method="close">
>                <property name="className"
>                        value="org.postgresql.xa.PGXADataSource" />
>                <property name="uniqueName" value="jdbc/ds2" />
>                <property name="minPoolSize" value="2" />
>                <property name="maxPoolSize" value="32" />
>                <property name="useTmJoin" value="true" />
>                <property name="allowLocalTransactions" value="false" />
>                <property name="driverProperties">
>                        <props>
>                                <prop key="serverName">localhost</prop>
>                                <prop key="databaseName">schema2</prop>
>                                <prop key="portNumber">5432</prop>
>                                <prop key="user">postgres</prop>
>                                <prop key="password">johnlennon</prop>
>                        </props>
>                </property>
>        </bean>
>
>        <!--  Bitronix Transaction Manager embedded configuration -->
>        <bean id="btmConfig" factory-method="getConfiguration"
>                class="bitronix.tm.TransactionManagerServices">
>                <property name="serverId" value="spring-btm" />
>        </bean>
>
>        <!-- create BTM transaction manager -->
>        <bean id="bitronixTransactionManager"
> factory-method="getTransactionManager"
>                class="bitronix.tm.TransactionManagerServices"
>                depends-on="btmConfig"
>                destroy-method="shutdown" />
>
>        <!-- Spring JtaTransactionManager -->
>        <bean id="jtaTransactionManager"
>                class="org.springframework.transaction.jta.JtaTransactionManager">
>                <property name="transactionManager" ref="bitronixTransactionManager" />
>                <property name="userTransaction" ref="bitronixTransactionManager" />
>        </bean>
>
>        <!-- Abstract Transaction Factory Proxy -->
>        <bean id="baseTransactionProxy"
>
> class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
>                abstract="true">
>                <property name="transactionManager" ref="jtaTransactionManager" />
>                <property name="transactionAttributes">
>                        <props>
>                                <prop key="save">PROPAGATION_REQUIRED, -Exception</prop>
>                        </props>
>                </property>
>                <property name="target" ref="simplePersonDaoImpl1" />
>        </bean>
>
>        <!-- Targets -->
>        <bean id="simplePersonDaoImpl1"
>                class="discoverybitronix.examples.dao.impl.SimplePersonDaoImpl1">
>                <property name="dataSource" ref="dataSource1" />
>        </bean>
>
>        <bean id="simplePersonDaoImpl2"
>                class="discoverybitronix.examples.dao.impl.SimplePersonDaoImpl1">
>                <property name="dataSource" ref="dataSource2" />
>        </bean>
>
>        <!-- Proxies -->
>        <bean id="proxy1" parent="baseTransactionProxy">
>                <property name="target" ref="simplePersonDaoImpl1" />
>        </bean>
>        <bean id="proxy2" parent="baseTransactionProxy">
>                <property name="target" ref="simplePersonDaoImpl2" />
>        </bean>
>
> </beans>
>
> Please help me handle this prob.
>
> Thanks!
> --
> View this message in context: http://old.nabble.com/Cannot-be-used-outside-XA-transaction-scope-tp29123955p29123955.html
> Sent from the Bitronix Transaction Manager mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Cannot be used outside XA transaction scope

Tran Duy Tung
In reply to this post by Tran Duy Tung
snicoll wrote
Hi,

Your jdbcTemplate has no transaction when it runs. Does
SimplePersonDaoImpl1#update creates the table ?

Anyway, your code is not within a transaction when it's looking up a
connection. By default, this is not allowed and it's probably what you
expect. You need to start a transaction by, for instance, adding a
@Transactional on your public save method and enable declarative
transaction in Spring (<tx:annotation-config/>).

Note that in the future if you are using something like hibernate, you
need to switch allowLocalTransactions to true as Hibernate will update
your schema without a transaction on startup (that's exactly what
you're having here, except it's your code and  you can fix it).

HTH,
Stéphane
Thank you. But after I add annotations to SimplePersonDaoImpl like this:
@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
public class SimplePersonDaoImpl1 extends SimpleJdbcDaoSupport implements SimplePersonDao {

        public void del(int pID) {
                // TODO Auto-generated method stub
        }

        public void edit(Person p) {
                // TODO Auto-generated method stub
        }

        @Transactional(propagation=Propagation.REQUIRED, readOnly=false)
        public void save(Person p) {
                String insertQuery = "INSERT INTO person(id, name) VALUES(?, ?)";
                getSimpleJdbcTemplate().update(insertQuery, p.getId(), p.getName());
        }
}

and in context xml of Spring I add this row:

<tx:annotation-driven transaction-manager="jtaTransactionManager" />

although I still let allowLocalTransactions=false and try to insert 2 rows to 2 schemas, one new row conflict primary key and one doesn't conflict, the row that doesn't conflict pk is inserted. That's not the "two-phase commit" strategy. Both 2 row must not be inserted.

And the log info: INFO: recovery committed 0 dangling transaction(s) and rolled back 0 aborted transaction(s) on 2 resource(s) [jdbc/ds2, jdbc/ds1] (restricted to serverId 'spring-btm') ---> that means 2 transaction branches did not join to the global transaction although I add some Annotation to the source code of SimplePersonDaoImpl. Bitronix is so complicate!

Reply | Threaded
Open this post in threaded view
|

Re: Cannot be used outside XA transaction scope

Ludovic Orban
Administrator
Since you annotated the save(Person) method with @Transactional it's quite normal you get one row inserted and not the other as transactions are started before the method gets called and committed when it returns.

You have to start the transaction _before_ you insert your rows and commit it after _both_ have been inserted, or tried to be. A common way of doing that is to wrap your DAO calls within a method of a service class witch itself gets @Transactional annotated.

BTM's easy to use, you configured it right. It's just that transactions are another business concept part of your business logic and not of the data access logic, something a lot of people tend to misunderstand.

You should also stop making wrong assumptions about the log messages. The recovery log you get just indicates that nothing got recovered because nothing crashed or failed in any way. This has absolutely nothing to do with branches in any way.
Reply | Threaded
Open this post in threaded view
|

Re: Cannot be used outside XA transaction scope

Tran Duy Tung
Ludovic Orban wrote
Since you annotated the save(Person) method with @Transactional it's quite normal you get one row inserted and not the other as transactions are started before the method gets called and committed when it returns.

You have to start the transaction _before_ you insert your rows and commit it after _both_ have been inserted, or tried to be. A common way of doing that is to wrap your DAO calls within a method of a service class witch itself gets @Transactional annotated.

BTM's easy to use, you configured it right. It's just that transactions are another business concept part of your business logic and not of the data access logic, something a lot of people tend to misunderstand.

You should also stop making wrong assumptions about the log messages. The recovery log you get just indicates that nothing got recovered because nothing crashed or failed in any way. This has absolutely nothing to do with branches in any way.
When I cofig the baseTransactionProxy:

<bean id="baseTransactionProxy"
                class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
                abstract="true">
                <property name="transactionManager" ref="jtaTransactionManager" />
                <property name="proxyInterfaces"
                        value="discoverybitronix.examples.dao.SimplePersonDao"/>
                <property name="transactionAttributes">
                        <props>
                                <prop key="save">PROPAGATION_REQUIRED, -Exception</prop>
                        </props>
                </property>
        </bean>

So, <prop key="save">PROPAGATION_REQUIRED, -Exception</prop> I think it indicates that the method must run within a transaction. If an existing transaction is in progress, the method will run within that transaction. Otherwise, a new transaction will be started automatically. If the method throws an exception, the global transaction should rollback automatically. Is that true?

Orban, I see you in so many forum that related to BTM. :)

Can you send me a simple example that use BTM + Spring that use JDBC (doesn't relate with JMS and JNDI)? Thanks so much!

Reply | Threaded
Open this post in threaded view
|

Re: Cannot be used outside XA transaction scope

Ludovic Orban-2
That's correct but you should never demarcate your transactions on your DAOs.

Reply | Threaded
Open this post in threaded view
|

RE: Cannot be used outside XA transaction scope

Jeff Jensen-2

Hmmm, I use MANDATORY on DAOs though, to help prevent noobs from, and others accidentally, skipping the service layer which have REQUIRED or other.  Would you argue against this? (you wrote never, so wondering how “never” you mean!?  My guess is your “demarcate” use means start and stop only? :-)

 

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Ludovic Orban
Sent: Saturday, July 10, 2010 9:09 AM
To: [hidden email]
Subject: Re: [btm-user] Cannot be used outside XA transaction scope

 

That's correct but you should never demarcate your transactions on your DAOs.

Reply | Threaded
Open this post in threaded view
|

Re: Cannot be used outside XA transaction scope

Tran Duy Tung
In reply to this post by Ludovic Orban-2
Please ignore my stupid structure design. My problem still not be handled. Please give me some good advices.

My email: tung-td@hipt.com.vn. Can any one send me a simple example that help me understand how to config bitronix and spring that doesn't relate with JDBC and JMS.

Reply | Threaded
Open this post in threaded view
|

Re: Cannot be used outside XA transaction scope

Ludovic Orban-2
In reply to this post by Jeff Jensen-2
Jeff,

That's a good policy I never though about, you can never have enough checks in your code.

What I meant is that the data access layer should never start or end a transaction as transaction control is part of the business logic.


2010/7/10 Jeff Jensen <[hidden email]>

Hmmm, I use MANDATORY on DAOs though, to help prevent noobs from, and others accidentally, skipping the service layer which have REQUIRED or other.  Would you argue against this? (you wrote never, so wondering how “never” you mean!?  My guess is your “demarcate” use means start and stop only? :-)

 

Reply | Threaded
Open this post in threaded view
|

RE: Cannot be used outside XA transaction scope

Jeff Jensen-2

Agreed, thanks for clarifying!  You meant as I thought.

 

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Ludovic Orban
Sent: Sunday, July 11, 2010 10:50 AM
To: [hidden email]
Subject: Re: [btm-user] Cannot be used outside XA transaction scope

 

Jeff,

That's a good policy I never though about, you can never have enough checks in your code.

What I meant is that the data access layer should never start or end a transaction as transaction control is part of the business logic.

2010/7/10 Jeff Jensen <[hidden email]>

Hmmm, I use MANDATORY on DAOs though, to help prevent noobs from, and others accidentally, skipping the service layer which have REQUIRED or other.  Would you argue against this? (you wrote never, so wondering how “never” you mean!?  My guess is your “demarcate” use means start and stop only? :-)