我正在尝试编写一个演示来了解spring事务。这是spring-config.xml中的配置:
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close" scope="prototype">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/test"/>
<property name="username" value="root"/>
<property name="password" value="#Bugsfor$"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="categoryDAOOperation" expression="execution(* com.ea.test.dao.CategoryDAO.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="categoryDAOOperation"/>
</aop:config>
<!-- define the SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations">
<list>
<value>classpath:mapper/CategoryMapper.xml</value>
</list>
</property>
</bean>
<bean id="categoryMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.ea.test.mapper.CategoryMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<bean id="categoryDAO" class="com.ea.test.dao.CategoryDAO">
<property name="categoryMapper" ref="categoryMapper"/>
</bean>
以下是CategoryDAO.java
public class CategoryDAO {
CategoryMapper categoryMapper;
public void setCategoryMapper(CategoryMapper categoryMapper) {
this.categoryMapper = categoryMapper;
}
public CategoryDB get(int id) {
logger.info("Start to get category for id: {}", id);
CategoryDB retValue = categoryMapper.get(id);
logger.info("Get category for id: {} successfully", id);
return retValue;
}
public void save(CategoryDB categoryDB) {
categoryMapper.save(categoryDB);
throw new UnsupportedOperationException("unsupported");
}
}
CategoryService.java
public class CategoryService {
public static void main(String[] args) throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {
"spring-config.xml"
});
CategoryDAO categoryDAO = (CategoryDAO) context.getBean("categoryDAO");
CategoryDB categoryDB = new CategoryDB();
categoryDB.setId(1);
categoryDB.setName("AAA");
categoryDAO.save(categoryDB);
}
}
这是运行时的DEBUG日志
08/07/15 12:22:40:344: [main]: DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@325dc1bc]]] for JDBC transaction
08/07/15 12:22:40:348: [main]: DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@325dc1bc]]] to manual commit
08/07/15 12:22:40:374: [main]: DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession
08/07/15 12:22:40:377: [main]: DEBUG org.mybatis.spring.SqlSessionUtils - Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@27589aa5]
08/07/15 12:22:40:407: [main]: DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
08/07/15 12:22:40:407: [main]: DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Registering transaction synchronization for JDBC Connection
08/07/15 12:22:40:407: [main]: DEBUG org.mybatis.spring.transaction.SpringManagedTransaction - JDBC Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@1d10e937]]] will be managed by Spring
08/07/15 12:22:40:408: [main]: DEBUG com.ea.test.mapper.CategoryMapper.save - ooo Using Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@1d10e937]]]
08/07/15 12:22:40:416: [main]: DEBUG com.ea.test.mapper.CategoryMapper.save - ==> Preparing: insert into CATEGORY ( CATEGORY_ID, CATEGORY_NAME ) values ( ?, ? )
08/07/15 12:22:40:456: [main]: DEBUG com.ea.test.mapper.CategoryMapper.save - ==> Parameters: 1(Integer), AAA(String)
08/07/15 12:22:40:492: [main]: DEBUG org.mybatis.spring.SqlSessionUtils - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@27589aa5]
08/07/15 12:22:40:493: [main]: DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Initiating transaction rollback
08/07/15 12:22:40:493: [main]: DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Rolling back JDBC transaction on Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@325dc1bc]]]
08/07/15 12:22:40:494: [main]: DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization rolling back SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@27589aa5]
08/07/15 12:22:40:494: [main]: DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@27589aa5]
08/07/15 12:22:40:494: [main]: DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
08/07/15 12:22:40:495: [main]: DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@325dc1bc]]] after transaction
08/07/15 12:22:40:495: [main]: DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
Exception in thread "main" java.lang.UnsupportedOperationException: unsupported
at com.ea.test.dao.CategoryDAO.save(CategoryDAO.java:40)
at com.ea.test.dao.CategoryDAO$$FastClassByCGLIB$$c0f75c81.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
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.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
at com.ea.test.dao.CategoryDAO$$EnhancerByCGLIB$$4d1a773e.save(<generated>)
at com.ea.test.service.CategoryService.main(CategoryService.java:25)
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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
CategoryDAO
抛出UnSupportedOperationExecption
,所以我认为CatetegoryMapper.save
会回滚。但事实并非如此。对于DataSource.defaultAutoCommit
为真,CatetegoryMapper.save
应该在抛出UnSupportedOperationExecption
之前提交。然后我将D ataSource.defaultAutoCommit
设置为false,但我发现CatetegoryMapper.save
将永远不会提交,无论是否抛出UnSupportedOperationExecption
。我不知道为什么。
我的配置文件中有什么问题,或者我对它有一些误解。非常感谢
答案 0 :(得分:0)
我知道配置有什么问题。我只是犯了一个非常愚蠢的错误。我将dataSource
的范围配置为prototype
。 sqlSessionFactory
和transactionManager
中有两个不同的dataSource。然后我删除它工作的范围
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/test"/>
<property name="username" value="root"/>
<property name="password" value="#Bugsfor$"/>
</bean>