天温习spring的事务处理机制,总结如下
事务管理器实现(org.springframework.*) | 使用时机 |
jdbc.datasource.DataSourceTransactionManager | 使用jdbc的抽象以及ibatis支持 |
orm.hibernate.HibernateTransactionManager | 使用hibernate支持(默认3.0以下版本) |
orm.hibernate3.HibernateTransactionManager | 使用hibernate3支持 |
transaction.jta.JtaTransactionManager | 使用分布式事务(分布式数据库支持) |
orm.jpa.JpaTransactionManager | 使用jpa做为持久化工具 |
orm.toplink.TopLinkTransactionManager | 使用TopLink持久化工具 |
orm.jdo.JdoTransactionManager | 使用Jdo持久化工具 |
jms.connection.JmsTransactionManager | 使用JMS 1.1+ |
jms.connection.JmsTransactionManager102 | 使用JMS 1.0.2 |
transaction.jta.OC4JJtaTransactionManager | 使用oracle的OC4J JEE容器 |
transaction.jta.WebLogicJtaTransactionManager | 在weblogic中使用分布式数据库 |
jca.cci.connection.CciLocalTransactionManager | 使用jrping对J2EE Connector Architecture (JCA)和Common Client Interface (CCI)的支持 |
UML结构图如下
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
传播行为 | 含义 |
PROPAGATION_REQUIRED(XML文件中为REQUIRED) | 表示当前方法必须在一个具有事务的上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。(如果被调用端发生异常,那么调用端和被调用端事务都将回滚) |
PROPAGATION_SUPPORTS(XML文件中为SUPPORTS) | 表示当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行 |
PROPAGATION_MANDATORY(XML文件中为MANDATORY) | 表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常 |
PROPAGATION_NESTED(XML文件中为NESTED) | 表示如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同PROPAGATION_REQUIRED的一样 |
PROPAGATION_NEVER(XML文件中为NEVER) | 表示当方法务不应该在一个事务中运行,如果存在一个事务,则抛出异常 |
PROPAGATION_REQUIRES_NEW(XML文件中为REQUIRES_NEW) | 表示当前方法必须运行在它自己的事务中。一个新的事务将启动,而且如果有一个现有的事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行。 |
PROPAGATION_NOT_SUPPORTED(XML文件中为NOT_SUPPORTED) | 表示该方法不应该在一个事务中运行。如果有一个事务正在运行,他将在运行期被挂起,直到这个事务提交或者回滚才恢复执行 |
隔离级别 | 含义 |
ISOLATION_DEFAULT | 使用数据库默认的事务隔离级别 |
ISOLATION_READ_UNCOMMITTED | 允许读取尚未提交的修改,可能导致脏读、幻读和不可重复读 |
ISOLATION_READ_COMMITTED | 允许从已经提交的事务读取,可防止脏读、但幻读,不可重复读仍然有可能发生 |
ISOLATION_REPEATABLE_READ | 对相同字段的多次读取的结果是一致的,除非数据被当前事务自生修改。可防止脏读和不可重复读,但幻读仍有可能发生 |
ISOLATION_SERIALIZABLE | 完全服从ACID隔离原则,确保不发生脏读、不可重复读、和幻读,但执行效率最低。 |
<tx:advice id="txAdvice" transactionManager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config> <aop:advisor pointcut="execution(* *..zx.spring.UserService*.*(..))||execution(* *..spring.ServiceFacade.*(..))||execution(* *..spring.BookService.*(..))" advice-ref="txAdvice"/> </aop:config>
CREATE TABLE T_USER( ID INT, NAME VARCHAR2(200) ); CREATE TABLE T_BOOK( ID INT , NAME VARCHAR2(200) );
<!-- 定义数据源 --> <bean id="ams" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.ams.driver}" /> <property name="jdbcUrl" value="${jdbc.ams.url}" /> <property name="user" value="${jdbc.ams.username}" /> <property name="password" value="${jdbc.ams.password}" /> <property name="initialPoolSize" value="${initialSize}" /> <property name="minPoolSize" value="${minPoolSize}" /> <property name="maxPoolSize" value="${maxActive}" /> <property name="acquireIncrement" value="${acquireIncrement}" /> <property name="maxIdleTime" value="${maxIdleTime}" /> </bean> <!-- 定义jdbc模板类--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="ams"/> </bean>
package com.zx.spring; import org.springframework.jdbc.core.JdbcTemplate; public class BookService { public static final String ADD_BOOK="insert into t_book(id,name) values(1,'duck-j2ee')"; private JdbcTemplate jdbcTemplate; public void addBook() throws Exception{ this.jdbcTemplate.execute(ADD_BOOK); throw new RollbackException("跳出执行"); } public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } }
package com.zx.spring; import org.springframework.jdbc.core.JdbcTemplate; public class UserService { public static final String ADD_USER="insert into t_user(id,name) values(1,'duck')"; private BookService bs; private JdbcTemplate jdbcTemplate; public void addUser()throws Exception { this.bs.addBook(); this.jdbcTemplate.execute(ADD_USER); } public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public BookService getBs() { return bs; } public void setBs(BookService bs) { this.bs = bs; } }
package com.zx.spring; public class ServiceFacade { private BookService bs; private UserService us; public BookService getBs() { return bs; } public void setBs(BookService bs) { this.bs = bs; } public UserService getUs() { return us; } public void setUs(UserService us) { this.us = us; } public void addUserBook()throws Exception{ bs.addBook(); us.addUser(); } }
<aop:config> <aop:advisor pointcut="execution(* *..zx.spring.UserService*.*(..))||execution(* *..spring.ServiceFacade.*(..))||execution(* *..spring.BookService.*(..))" advice-ref="txAdvice"/> </aop:config>
@Test public void testAddBook()throws Exception{ BookService bs=(BookService)this.getBean("bookService"); bs.addBook(); }
public void addBook() throws Exception{ this.jdbcTemplate.execute(ADD_BOOK); throw new RuntimeException("throw runtime exception in outter transaction"); }
1、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 2、[DEBUG,DataSourceTransactionManager,main] Initiating transaction rollback 3、[DEBUG,DataSourceTransactionManager,main] Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@a2b392]
public void addBook() throws Exception{ this.jdbcTemplate.execute(ADD_BOOK); throw new Exception("throw runtime exception in outter transaction"); }
1、[DEBUG,DataSourceTransactionManager,main] Creating new transaction with name [com.zx.spring.BookService.addBook]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 2、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 3、[DEBUG,DataSourceTransactionManager,main] Initiating transaction commit 4、[DEBUG,DataSourceTransactionManager,main] Committing JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@4310d0]
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="addUser" propagation="REQUIRED" /> <tx:method name="addBook" propagation="MANDATORY"/> </tx:attributes> </tx:advice>
org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory' at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:357)
1、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 2、[DEBUG,DataSourceUtils,main] Registering transaction synchronization for JDBC Connection 3、[DEBUG,DataSourceTransactionManager,main] Should roll back transaction but cannot - no transaction available
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="addUser" propagation="REQUIRED"/> <tx:method name="addBook" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
1、public void addUser()throws Exception { 2、 this.bs.addBook(); 3、 this.jdbcTemplate.execute(ADD_USER); }
4、public void addBook() throws Exception{ 5、 this.jdbcTemplate.execute(ADD_BOOK); 6、 throw new RuntimeException("跳出执行"); }
@Test public void testAddUser()throws Exception{ UserService us=(UserService)this.getBean("userService"); us.addUser(); }
[DEBUG,DataSourceTransactionManager,main] Creating new transaction with name [com.zx.spring.UserService.addUser]:
PROPAGATION_REQUIRED,ISOLATION_DEFAULT上面输出可以知道,spring自动给addUser()方法切入了事务,事务隔离级别为数据库默认级别。
1、[DEBUG,DataSourceTransactionManager,main] Acquired Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1973fc5] for JDBC transaction 2、[DEBUG,DataSourceTransactionManager,main] Switching JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1973fc5] to manual commit 3、[DEBUG,DataSourceTransactionManager,main] Participating in existing transaction 4、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 5、[DEBUG,DataSourceTransactionManager,main] Participating transaction failed - marking existing transaction as rollback-only 6、[DEBUG,DataSourceTransactionManager,main] Setting JDBC transaction [com.mchange.v2.c3p0.impl.NewProxyConnection@1973fc5] rollback-only 7、[DEBUG,DataSourceTransactionManager,main] Initiating transaction rollback 8、[DEBUG,DataSourceTransactionManager,main] Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1973fc5]
7、public void addBook() throws Exception{ 8、 this.jdbcTemplate.execute(ADD_BOOK); 9、 throw new Exception("跳出执行"); }
9、[DEBUG,DataSourceTransactionManager,main] Acquired Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1973fc5] for JDBC transaction 10、[DEBUG,DataSourceTransactionManager,main] Switching JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1973fc5] to manual commit 11、[DEBUG,DataSourceTransactionManager,main] Participating in existing transaction 12、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 13、[DEBUG,DataSourceTransactionManager,main] Initiating transaction commit 14、[DEBUG,DataSourceTransactionManager,main] Releasing JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@457d21] after transaction
public void addBook() throws Exception{ this.jdbcTemplate.execute(ADD_BOOK); throw new Exception("跳出执行"); }
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="addUser" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="addBook" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
15、[DEBUG,DataSourceTransactionManager,main] Participating in existing transaction 16、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 17、[DEBUG,DataSourceTransactionManager,main] Initiating transaction rollback 18、[DEBUG,DataSourceTransactionManager,main] Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@121d383]可见,当指定了rollback-for属性时,只要抛出了指定的异常,事务就会回滚。
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="addUser" propagation="REQUIRED" /> <tx:method name="addBook" propagation="NEVER"/> </tx:attributes> </tx:advice>执行Junit测试后发现,控制台输出如下:
org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never' at org.springframework.transaction.support.AbstractPlatformTransactionManager.handleExistingTransaction(AbstractPlatformTransactionManager.java:399) at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:347) at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335)Existing transaction found for transaction marked with propagation 'never',也就是说addBook不应该在事务中运行,但是addUser这个客户端调用者却有一个事务,因此报错。
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="addUser" propagation="REQUIRED" /> <tx:method name="addBook" propagation="MANDATORY"/> </tx:attributes> </tx:advice>执行junit后,控制台输出如下
[DEBUG,DataSourceTransactionManager,main] Participating in existing transaction [DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] [DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_user(id,name) values(1,'duck')] [DEBUG,DataSourceTransactionManager,main] Initiating transaction commit可以知道当前和REQUIRED一样的传播行为。
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="addUser" propagation="REQUIRED" /> <tx:method name="addBook" propagation="NESTED"/> </tx:attributes> </tx:advice>
addBook()方法如下,依然抛出(checked-exception)检查异常。
public void addBook() throws Exception{ this.jdbcTemplate.execute(ADD_BOOK); throw new RuntimeException("跳出执行"); }
addUser()方法如下,在方法体中捕获addBook()抛出的异常。如果不捕获异常,addUser()方法将会被终止。
public void addUser()throws Exception { try { this.bs.addBook(); }catch(Exception e) { e.printStackTrace(); } this.jdbcTemplate.execute(ADD_USER); }执行junit后,控制台输出如下
1、[DEBUG,DataSourceTransactionManager,main] Creating new transaction with name [com.zx.spring.UserService.addUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 2、[DEBUG,DataSourceTransactionManager,main] Creating nested transaction with name [com.zx.spring.BookService.addBook] 3、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 4、[DEBUG,DataSourceTransactionManager,main] Rolling back transaction to savepoint 5、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_user(id,name) values(1,'duck')] 6、[DEBUG,DataSourceTransactionManager,main] Initiating transaction commit 7、[DEBUG,DataSourceTransactionManager,main] Committing JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@10e164e]
java.sql.SQLException: 不支持的特性 at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146) at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
public void addUser()throws Exception { this.bs.addBook(); this.jdbcTemplate.execute(ADD_USER); throw new RuntimeException("throw runtime exception in outter transaction"); }
public void addBook() throws Exception{ this.jdbcTemplate.execute(ADD_BOOK); }
1、[DEBUG,DataSourceTransactionManager,main] Creating new transaction with name [com.zx.spring.UserService.addUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 2、[DEBUG,DataSourceTransactionManager,main] Creating nested transaction with name [com.zx.spring.BookService.addBook] 3、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 4、[DEBUG,DataSourceTransactionManager,main] Releasing transaction savepoint 5、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_user(id,name) values(1,'duck')] 6、[DEBUG,DataSourceTransactionManager,main] Initiating transaction rollback 7、[DEBUG,DataSourceTransactionManager,main] Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1622a94]
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="addUser" propagation="REQUIRED" /> <tx:method name="addBook" propagation="REQUIRES_NEW"/> </tx:attributes> </tx:advice>
public void addUser()throws Exception { this.bs.addBook(); this.jdbcTemplate.execute(ADD_USER); }
public void addBook() throws Exception{ this.jdbcTemplate.execute(ADD_BOOK); //throw new RuntimeException("throw runtime exception in outter transaction"); }
1、[DEBUG,DataSourceTransactionManager,main] Creating new transaction with name [com.zx.spring.UserService.addUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 2、[DEBUG,DataSourceTransactionManager,main] Suspending current transaction, creating new transaction with name [com.zx.spring.BookService.addBook] 3、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 4、[DEBUG,DataSourceTransactionManager,main] Initiating transaction commit 5、[DEBUG,DataSourceTransactionManager,main] Committing JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@5b96c2]
public void addUser()throws Exception { 1、 this.bs.addBook(); 2、 this.jdbcTemplate.execute(ADD_USER); }
public void addUser()throws Exception { this.jdbcTemplate.execute(ADD_USER); this.bs.addBook(); }
1、[DEBUG,DataSourceTransactionManager,main] Creating new transaction with name [com.zx.spring.UserService.addUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 2、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_user(id,name) values(1,'duck')] 3、[DEBUG,DataSourceTransactionManager,main] Suspending current transaction, creating new transaction with name [com.zx.spring.BookService.addBook] 4、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 5、[DEBUG,DataSourceTransactionManager,main] Initiating transaction commit 6、[DEBUG,DataSourceTransactionManager,main] Committing JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1b7ae22] 7、[DEBUG,DataSourceTransactionManager,main] Resuming suspended transaction after completion of inner transaction 8、[DEBUG,DataSourceTransactionManager,main] Initiating transaction commit 9、[DEBUG,DataSourceTransactionManager,main] Committing JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1fa681c]
public void addBook() throws Exception{ this.jdbcTemplate.execute(ADD_BOOK); throw new RuntimeException("throw runtime exception in outter transaction"); }
public void addUser()throws Exception { this.jdbcTemplate.execute(ADD_USER); this.bs.addBook(); }
1、[DEBUG,DataSourceTransactionManager,main] Creating new transaction with name [com.zx.spring.UserService.addUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 2、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_user(id,name) values(1,'duck')] 3、[DEBUG,DataSourceTransactionManager,main] Suspending current transaction, creating new transaction with name [com.zx.spring.BookService.addBook] 4、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 5、[DEBUG,DataSourceTransactionManager,main] Initiating transaction rollback 6、[DEBUG,DataSourceTransactionManager,main] Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@10d0b72] 7、[DEBUG,DataSourceTransactionManager,main] Releasing JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@10d0b72] after transaction 8、[DEBUG,DataSourceTransactionManager,main] Resuming suspended transaction after completion of inner transaction8、 9、[DEBUG,DataSourceTransactionManager,main] Initiating transaction rollback 10、[DEBUG,DataSourceTransactionManager,main] Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@44b361] 11、[DEBUG,DataSourceTransactionManager,main] Releasing JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@44b361] after transaction
public void addUser()throws Exception { this.jdbcTemplate.execute(ADD_USER); try { this.bs.addBook(); }catch(Exception e) { e.printStackTrace(); } }
1、[DEBUG,DataSourceTransactionManager,main] Creating new transaction with name [com.zx.spring.UserService.addUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 2、[DEBUG,DataSourceTransactionManager,main] Acquired Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1bcec19] for JDBC transaction 3、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_user(id,name) values(1,'duck')] 4、[DEBUG,DataSourceTransactionManager,main] Suspending current transaction, creating new transaction with name [com.zx.spring.BookService.addBook] 5、[DEBUG,DataSourceTransactionManager,main] Acquired Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@ba507b] for JDBC transaction 6、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 7、[DEBUG,DataSourceTransactionManager,main] Initiating transaction rollback 8、[DEBUG,DataSourceTransactionManager,main] Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@ba507b] 9、[DEBUG,DataSourceTransactionManager,main] Resuming suspended transaction after completion of inner transaction 10、java.lang.RuntimeException: throw runtime exception in outter transaction at com.zx.spring.BookService.addBook(BookService.java:11) 11、[DEBUG,DataSourceTransactionManager,main] Initiating transaction commit 12、[DEBUG,DataSourceTransactionManager,main] Committing JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1bcec19]
public void addUser()throws Exception { this.jdbcTemplate.execute(ADD_USER); this.bs.addBook(); }
1、[DEBUG,DataSourceTransactionManager,main] Creating new transaction with name [com.zx.spring.UserService.addUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 2、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_user(id,name) values(1,'duck')] 3、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 4、[DEBUG,DataSourceTransactionManager,main] Initiating transaction rollback 5、[DEBUG,DataSourceTransactionManager,main] Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@63a721] 6、[DEBUG,DataSourceTransactionManager,main] Resuming suspended transaction after completion of inner transaction 7、[DEBUG,DataSourceTransactionManager,main] Initiating transaction rollback 8、[DEBUG,DataSourceTransactionManager,main] Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1706da8]
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="addUser" propagation="REQUIRED" /> <tx:method name="addBook" propagation="SUPPORTS"/> </tx:attributes> </tx:advice>
public void addUser()throws Exception { this.bs.addBook(); this.jdbcTemplate.execute(ADD_USER); }
public void addBook() throws Exception{ this.jdbcTemplate.execute(ADD_BOOK); throw new RuntimeException("throw runtime exception in outter transaction"); }
1、[DEBUG,DataSourceTransactionManager,main] Creating new transaction with name [com.zx.spring.UserService.addUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 2、[DEBUG,DataSourceTransactionManager,main] Participating in existing transaction 3、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')]
4、[DEBUG,DataSourceTransactionManager,main] Participating transaction failed - marking existing transaction as rollback-only 5、[DEBUG,DataSourceTransactionManager,main] Setting JDBC transaction [com.mchange.v2.c3p0.impl.NewProxyConnection@19e09a4] rollback-only 6、[DEBUG,DataSourceTransactionManager,main] Initiating transaction rollback 7、[DEBUG,DataSourceTransactionManager,main] Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@19e09a4]
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="addUser" propagation="REQUIRED" /> <tx:method name="addBook" propagation="NOT_SUPPORTED"/> </tx:attributes> </tx:advice>
public void addBook() throws Exception{ this.jdbcTemplate.execute(ADD_BOOK); throw new RuntimeException("throw runtime exception in outter transaction"); }
public void addUser()throws Exception { this.bs.addBook(); this.jdbcTemplate.execute(ADD_USER); }
1、[DEBUG,DataSourceTransactionManager,main] Creating new transaction with name [com.zx.spring.UserService.addUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 2、[DEBUG,DataSourceTransactionManager,main] Suspending current transaction 3、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 4、[DEBUG,DataSourceUtils,main] Fetching JDBC Connection from DataSource 5、[DEBUG,DataSourceTransactionManager,main] Should roll back transaction but cannot - no transaction available 6、[DEBUG,DataSourceTransactionManager,main] Resuming suspended transaction after completion of inner transaction 7、[DEBUG,DataSourceTransactionManager,main] Initiating transaction rollback 8、[DEBUG,DataSourceTransactionManager,main] Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@137d4a4]
public void addUser()throws Exception { try { this.bs.addBook(); }catch(Exception e) { e.printStackTrace(); } this.jdbcTemplate.execute(ADD_USER); }
今天对spring事务7中传播机制之间的作用进行了一个回顾,这里只涉及了jdbc事务管理器的特性,可能会有各种疏忽,希望各位读者拍砖。