问题
I am trying set up transaction but without success. Here is my code:
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
.......
<property name="defaultAutoCommit" value="false" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis-configuration.xml" />
<property name="dataSource" ref="dataSource" />
</bean>
@Transactional
private void prcessTransaction(...) {
delete(...);
//insert:
for(Item item: itemList){
insert(item)
}
}
<delete id="delete" parameterType="map">
delete from .....
</delete>
<insert id="insert" parameterType="Item">
insert into ....
</insert>
It looks like that prcessTransaction method is not only one transaction but sets of multiple transactions.
I am using Spring 3.0.5, myBatis 3.0.4, mybatis-spring-1.0.1, Tomcat 7.0.19, Oracle 11.1.0.6.0
Thanks for help.
回答1:
Putting @transactional on a private method looks problematic, the Spring documentation says:
In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.
The same section has this aside:
Method visibility and @Transactional
When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.
回答2:
We had a similar problem, but in a more complex environment where we have 2 databases with their own transaction manager each. The only way we got it to work was to specify the transaction manager instance on the @Transactional("transactionManager")
annotation.
It works, though I'm left unsatisfied as I don't understand why we need to explicitly specify the transaction manager on the annotation.
来源:https://stackoverflow.com/questions/7085271/how-to-set-up-transaction-with-mybatis-and-spring