Spring 事务调试
1, 关于sring怎么去配置事务,网上已有很多了,不在此介绍了,但有个问题,有多少人知道Spring的声明式事务是否已起作用,在此主要介绍怎么调试spring事务 。
2, 准备一项目 ,
log4j.xml 中 加入:
<logger name="org.springframework.transaction" additivity="false">
<level value="debug" /> 把这个改为deubg就可以
<!-- for development environment -->
<appender-ref ref="ConsoleAppender" />
</logger>
<logger name="org.springframework.transaction.interceptor.TransactionInterceptor" additivity="false">
<level value="debug" /> 把这个改为deubg就可以
<!-- for development environment -->
<appender-ref ref="ConsoleAppender" />
</logger>
当然,在log4j.properties 中也有相应的,
加入:
log4j.logger.org.springframework=debug 就可以了
3, spring的事务配置方法有N多,
在此列一种:
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager" >
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" rollback-for="SqlExecutorException"/>
<tx:method name="*" propagation="REQUIRED" read-only="true" no-rollback-for="SqlExecutorException"/>
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="false"> <!-- 是否使用cglib代理 -->
<aop:pointcut expression="execution(* org.com.spring.test.ioc01.TestTransManager.*(..))" id="managerTx"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="managerTx"/>
</aop:config>
4, 主要程序代码为: 同时 insert 两条,先看看调试时发出的日志,当然也可以是N条
public void saveTest_1() throws SqlExecutorException
{
this.sqlExecutor.update("insert into test_1(id,name,code) values(23,'33','454')", null) ;
this.sqlExecutor.update("insert into test_1(id,name,code) values(5,'33','454')", null) ;
}
:
Creating new transaction with name [org.com.spring.test.ioc01.TestTransManager.saveTest_1]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,-SqlExecutorException
2012-09-12 05:22:17,655:DEBUG DriverManagerDataSource main - Creating new JDBC DriverManager Connection to [jdbc:oracle:thin:@135.192.71.136:1521:orcl]
2012-09-12 05:22:18,265:DEBUG DataSourceTransactionManager main - Acquired Connection [oracle.jdbc.driver.T4CConnection@dc41c5] for JDBC transaction
2012-09-12 05:22:18,265:DEBUG DataSourceTransactionManager main - Switching JDBC Connection [oracle.jdbc.driver.T4CConnection@dc41c5] to manual commit
2012-09-12 05:22:18,265:DEBUG TransactionSynchronizationManager main - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@5c3987] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@3afb99] to thread [main]
2012-09-12 05:22:18,265:DEBUG TransactionSynchronizationManager main - Initializing transaction synchronization
2012-09-12 05:22:18,265:DEBUG TransactionInterceptor main - Getting transaction for [org.com.spring.test.ioc01.TestTransManager.saveTest_1]
2012-09-12 05:22:18,280:DEBUG JdbcTemplate main - Executing prepared SQL update
2012-09-12 05:22:18,280:DEBUG JdbcTemplate main - Executing prepared SQL statement [insert into test_1(id,name,code) values(23,'33','454')]
2012-09-12 05:22:18,280:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@5c3987] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@3afb99] bound to thread [main]
2012-09-12 05:22:18,515:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@5c3987] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@3afb99] bound to thread [main]
2012-09-12 05:22:18,515:DEBUG JdbcTemplate main - SQL update affected 1 rows
2012-09-12 05:22:18,530:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@5c3987] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@3afb99] bound to thread [main]
2012-09-12 05:22:18,530:DEBUG SpringJdbcSqlExecutor main - Time-consuming:250ms | insert into test_1(id,name,code) values(23,'33','454')
SpringJdbcSqlExecutor pringSql console method times is : 250ms | insert into test_1(id,name,code) values(23,'33','454')
2012-09-12 05:22:18,530:DEBUG JdbcTemplate main - Executing prepared SQL update
2012-09-12 05:22:18,530:DEBUG JdbcTemplate main - Executing prepared SQL statement [insert into test_1(id,name,code) values(24,'33','454')]
2012-09-12 05:22:18,530:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@5c3987] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@3afb99] bound to thread [main]
2012-09-12 05:22:18,530:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@5c3987] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@3afb99] bound to thread [main]
2012-09-12 05:22:18,530:DEBUG JdbcTemplate main - SQL update affected 1 rows
2012-09-12 05:22:18,530:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@5c3987] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@3afb99] bound to thread [main]
2012-09-12 05:22:18,530:DEBUG SpringJdbcSqlExecutor main - Time-consuming:0ms | insert into test_1(id,name,code) values(24,'33','454')
SpringJdbcSqlExecutor pringSql console method times is : 0ms | insert into test_1(id,name,code) values(24,'33','454')
2012-09-12 05:22:18,530:DEBUG TransactionInterceptor main - Completing transaction for [org.com.spring.test.ioc01.TestTransManager.saveTest_1]
2012-09-12 05:22:18,530:DEBUG DataSourceTransactionManager main - Triggering beforeCommit synchronization
2012-09-12 05:22:18,530:DEBUG DataSourceTransactionManager main - Triggering beforeCompletion synchronization
2012-09-12 05:22:18,530:DEBUG DataSourceTransactionManager main - Initiating transaction commit
中间SQL打印两次,有一次是本人程序打印出来的,
5,再来一个insert 已有的 :
public void saveTest_1() throws SqlExecutorException
{
this.sqlExecutor.update("insert into test_1(id,name,code) values(25,'33','454')", null) ; 25是新加的
this.sqlExecutor.update("insert into test_1(id,name,code) values(24,'33','454')", null) ; 24是已有的
} 看看 25会不会加进去
:
Creating new transaction with name [org.com.spring.test.ioc01.TestTransManager.saveTest_1]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,-SqlExecutorException
2012-09-12 05:25:12,468:DEBUG DriverManagerDataSource main - Creating new JDBC DriverManager Connection to [jdbc:oracle:thin:@135.192.71.136:1521:orcl]
2012-09-12 05:25:13,077:DEBUG DataSourceTransactionManager main - Acquired Connection [oracle.jdbc.driver.T4CConnection@14e113b] for JDBC transaction
2012-09-12 05:25:13,077:DEBUG DataSourceTransactionManager main - Switching JDBC Connection [oracle.jdbc.driver.T4CConnection@14e113b] to manual commit
2012-09-12 05:25:13,077:DEBUG TransactionSynchronizationManager main - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@147917a] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@c4d04d] to thread [main]
2012-09-12 05:25:13,077:DEBUG TransactionSynchronizationManager main - Initializing transaction synchronization
2012-09-12 05:25:13,077:DEBUG TransactionInterceptor main - Getting transaction for [org.com.spring.test.ioc01.TestTransManager.saveTest_1]
2012-09-12 05:25:13,093:DEBUG JdbcTemplate main - Executing prepared SQL update
2012-09-12 05:25:13,093:DEBUG JdbcTemplate main - Executing prepared SQL statement [insert into test_1(id,name,code) values(25,'33','454')]
2012-09-12 05:25:13,093:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@147917a] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@c4d04d] bound to thread [main]
2012-09-12 05:25:13,327:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@147917a] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@c4d04d] bound to thread [main]
2012-09-12 05:25:13,358:DEBUG JdbcTemplate main - SQL update affected 1 rows
2012-09-12 05:25:13,374:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@147917a] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@c4d04d] bound to thread [main]
2012-09-12 05:25:13,374:DEBUG SpringJdbcSqlExecutor main - Time-consuming:297ms | insert into test_1(id,name,code) values(25,'33','454')
SpringJdbcSqlExecutor pringSql console method times is : 297ms | insert into test_1(id,name,code) values(25,'33','454')
2012-09-12 05:25:13,499:DEBUG JdbcTemplate main - Executing prepared SQL update
2012-09-12 05:25:13,499:DEBUG JdbcTemplate main - Executing prepared SQL statement [insert into test_1(id,name,code) values(24,'33','454')]
2012-09-12 05:25:13,499:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@147917a] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@c4d04d] bound to thread [main]
2012-09-12 05:25:13,499:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@147917a] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@c4d04d] bound to thread [main]
2012-09-12 05:25:13,530:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@147917a] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@c4d04d] bound to thread [main]
2012-09-12 05:25:13,530:INFO XmlBeanDefinitionReader main - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
2012-09-12 05:25:13,530:DEBUG DefaultDocumentLoader main - Using JAXP provider [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl]
2012-09-12 05:25:13,530:DEBUG BeansDtdResolver main - Trying to resolve XML entity with public ID [-//SPRING//DTD BEAN 2.0//EN] and system ID [http://www.springframework.org/dtd/spring-beans-2.0.dtd]
2012-09-12 05:25:13,530:DEBUG BeansDtdResolver main - Trying to locate [spring-beans-2.0.dtd] in Spring jar
2012-09-12 05:25:13,546:DEBUG BeansDtdResolver main - Found beans DTD [http://www.springframework.org/dtd/spring-beans-2.0.dtd] in classpath: spring-beans-2.0.dtd
2012-09-12 05:25:13,546:DEBUG DefaultBeanDefinitionDocumentReader main - Loading bean definitions
2012-09-12 05:25:13,562:DEBUG DefaultListableBeanFactory main - Creating shared instance of singleton bean 'DB2'
2012-09-12 05:25:13,562:DEBUG DefaultListableBeanFactory main - Creating instance of bean 'DB2'
2012-09-12 05:25:13,562:DEBUG DefaultListableBeanFactory main - Eagerly caching bean 'DB2' to allow for resolving potential circular references
2012-09-12 05:25:13,562:DEBUG CachedIntrospectionResults main - Getting BeanInfo for class [org.springframework.jdbc.support.SQLErrorCodes]
[org.springframework.beans.propertyeditors.StringArrayPropertyEditor@14e45b3]
2012-09-12 05:25:13,577:DEBUG DefaultListableBeanFactory main - Finished creating instance of bean 'DB2'
..................................
2012-09-12 05:25:14,140:INFO SQLErrorCodesFactory main - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
2012-09-12 05:25:14,140:DEBUG SQLErrorCodesFactory main - Looking up default SQLErrorCodes for DataSource [org.springframework.jdbc.datasource.DriverManagerDataSource@c4d04d]
2012-09-12 05:25:14,140:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@147917a] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@c4d04d] bound to thread [main]
2012-09-12 05:25:14,140:DEBUG TransactionSynchronizationManager main - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@147917a] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@c4d04d] bound to thread [main]
2012-09-12 05:25:14,140:DEBUG SQLErrorCodesFactory main - Database product name cached for DataSource [org.springframework.jdbc.datasource.DriverManagerDataSource@c4d04d]: name is 'Oracle'
2012-09-12 05:25:14,140:DEBUG SQLErrorCodesFactory main - SQL error codes for 'Oracle' found
2012-09-12 05:25:14,140:DEBUG SQLErrorCodeSQLExceptionTranslator main - Translating SQLException with SQL state '23000', error code '1', message [ORA-00001: 违反唯一约束条件 (TELANT0815.SYS_C0056420)
]; SQL was [insert into test_1(id,name,code) values(24,'33','454')] for task [PreparedStatementCallback]
2012-09-12 05:25:14,140:DEBUG SpringJdbcSqlExecutor main - Time-consuming:0ms | insert into test_1(id,name,code) values(24,'33','454')
SpringJdbcSqlExecutor pringSql console method times is : 0ms | insert into test_1(id,name,code) values(24,'33','454')
2012-09-12 05:25:14,140:DEBUG TransactionInterceptor main - Completing transaction for [org.com.spring.test.ioc01.TestTransManager.saveTest_1] after exception: oss.com.spring.engin.jdbc.SqlExecutorException:
2012-09-12 05:25:14,140:DEBUG RuleBasedTransactionAttribute main - Applying rules to determine whether transaction should rollback on oss.com.spring.engin.jdbc.SqlExecutorException:
2012-09-12 05:25:14,140:DEBUG RuleBasedTransactionAttribute main - Winning rollback rule is: RollbackRuleAttribute with pattern [SqlExecutorException]
2012-09-12 05:25:14,140:DEBUG DataSourceTransactionManager main - Triggering beforeCompletion synchronization
2012-09-12 05:25:14,140:DEBUG DataSourceTransactionManager main - Initiating transaction rollback
2012-09-12 05:25:14,140:DEBUG DataSourceTransactionManager main - Rolling back JDBC transaction on Connection [oracle.jdbc.driver.T4CConnection@14e113b]
2012-09-12 05:25:14,140:DEBUG DataSourceTransactionManager main - Triggering afterCompletion synchronization
2012-09-12 05:25:14,140:DEBUG TransactionSynchronizationManager main - Clearing transaction synchronization
2012-09-12 05:25:14,140:DEBUG TransactionSynchronizationManager main - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@147917a] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@c4d04d] from thread [main]
2012-09-12 05:25:14,140:DEBUG DataSourceTransactionManager main - Releasing JDBC Connection [oracle.jdbc.driver.T4CConnection@14e113b] after transaction
2012-09-12 05:25:14,140:DEBUG DataSourceUtils main - Returning JDBC Connection to DataSource
2012-09-12 05:25:14,140:DEBUG DataSourceTransactionManager main - Releasing JDBC Connection [oracle.jdbc.driver.T4CConnection@14e113b] after transaction
可以看到 已经 rollback 了,查看库中也没 insert 进去
6,说明:
本人使用的是Oracle ,如果你使用的数据库本身不支持事务的话,光依靠 Spring的事务也没有用,Spring也是使用底层数据库的事务机制。