《Spring 2.0技术手册》 读书笔记七-Spring的DAO框架(3)-JDBC事务管理

Spring提供了编程式事务管理(programmatic transaction management)与声明式事务管理(declarative transaction management)。由于编程式事务管理会导致Spring框架侵入代码,而且变更复杂,故不赞成使用编程式事务管理。因此该篇笔记以声明式事务管理为主。

事务是一组原子操作的工作单元,在数据库存取中,就是一组SQL指令,它们必须全部执行成功,因为某个原因未全部成功,则先前所有执行过的SQL指令都要被撤销。

1. JDBC的事务管理

[java]  view plain copy
  1. try{  
  2. connection.setAutoCommit(false);  
  3. ...//一连串SQL操作  
  4. connection.commit();  
  5. }catch(SQLException){  
  6. //发生错误,撤销所有变更  
  7. connection.rollback();  
  8. }  
 

2. Spring的事务管理

Spring对JDBC的事务管理加以封装,关键是对org.springframework.transaction.PlatformTransactionManager接口的实现,DataSourceTransactionManager,HibernateTransactionManager等实现了此接口:

[java]  view plain copy
  1. public interface PlatformTransactionManager {  
  2.     /** 
  3.      * Return a currently active transaction or create a new one, according to 
  4.      * the specified propagation behavior. 
  5.      * @param definition TransactionDefinition instance (can be <code>null</code> for defaults), 
  6.      * describing propagation behavior, isolation level, timeout etc. 
  7.      * @return transaction status object representing the new or current transaction 
  8.      */  
  9.     TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;  
  10.     /** 
  11.      * Commit the given transaction, with regard to its status. If the transaction 
  12.      * has been marked rollback-only programmatically, perform a rollback. 
  13.      * <p>If the transaction wasn't a new one, omit the commit for proper 
  14.      * participation in the surrounding transaction. If a previous transaction 
  15.      * has been suspended to be able to create a new one, resume the previous 
  16.      * transaction after committing the new one. 
  17.      * <p>Note that when the commit call completes, no matter if normally or 
  18.      * throwing an exception, the transaction must be fully completed and 
  19.      * cleaned up. No rollback call should be expected in such a case. 
  20.      * <p>If this method throws an exception other than a TransactionException, 
  21.      * then some before-commit error caused the commit attempt to fail. For 
  22.      * example, an O/R Mapping tool might have tried to flush changes to the 
  23.      * database right before commit, with the resulting DataAccessException 
  24.      * causing the transaction to fail. The original exception will be 
  25.      * propagated to the caller of this commit method in such a case. 
  26.      * @param status object returned by the <code>getTransaction</code> method 
  27.      */  
  28.     void commit(TransactionStatus status) throws TransactionException;  
  29.     /** 
  30.      * Perform a rollback of the given transaction. 
  31.      * <p>If the transaction wasn't a new one, just set it rollback-only for proper 
  32.      * participation in the surrounding transaction. If a previous transaction 
  33.      * has been suspended to be able to create a new one, resume the previous 
  34.      * transaction after rolling back the new one. 
  35.      * <p><b>Do not call rollback on a transaction if commit threw an exception.</b> 
  36.      * The transaction will already have been completed and cleaned up when commit 
  37.      * returns, even in case of a commit exception. Consequently, a rollback call 
  38.      * after commit failure will lead to an IllegalTransactionStateException. 
  39.      * @param status object returned by the <code>getTransaction</code> method 
  40.      */  
  41.     void rollback(TransactionStatus status) throws TransactionException;  
  42. }  
 

其中,org.springframework.transaction.TransactionDefinition接口的实例定义了事务的隔离程度、传播行为、超时、只读等。

[java]  view plain copy
  1. public interface TransactionDefinition {  
  2.     int PROPAGATION_REQUIRED = 0;  
  3.     int PROPAGATION_SUPPORTS = 1;  
  4.     int PROPAGATION_MANDATORY = 2;  
  5.     int PROPAGATION_REQUIRES_NEW = 3;  
  6.     int PROPAGATION_NOT_SUPPORTED = 4;  
  7.     int PROPAGATION_NEVER = 5;  
  8.     int PROPAGATION_NESTED = 6;  
  9.     int ISOLATION_DEFAULT = -1;  
  10.     int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;  
  11.     int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;  
  12.     int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;  
  13.     int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;  
  14.     int TIMEOUT_DEFAULT = -1;  
  15.     /** Return the propagation behavior. */  
  16.     int getPropagationBehavior();  
  17.     /** Return the isolation level. */  
  18.     int getIsolationLevel();  
  19.     /** Return the transaction timeout. */  
  20.     int getTimeout();  
  21.     /*** Return whether to optimize as a read-only transaction. */  
  22.     boolean isReadOnly();  
  23.     /** 
  24.      * Return the name of this transaction. Can be <code>null</code>. 
  25.      * <p>This will be used as the transaction name to be shown in a 
  26.      * transaction monitor, if applicable (for example, WebLogic's). 
  27.      */  
  28.     String getName();  
  29. }  
 

org.springframework.transaction.TransactionStatus代表着一个新的事务发起或已经存在的事务,通过它可以控制事务的执行、设置状态。

[java]  view plain copy
  1. public interface TransactionStatus extends SavepointManager {  
  2.     /** 
  3.      * Return whether the present transaction is new (else participating 
  4.      * in an existing transaction, or potentially not running in an 
  5.      * actual transaction in the first place). 
  6.      */  
  7.     boolean isNewTransaction();  
  8.     /** 
  9.      * Return whether this transaction internally carries a savepoint, 
  10.      * that is, has been created as nested transaction based on a savepoint. 
  11.      */  
  12.     boolean hasSavepoint();  
  13.     /** 
  14.      * Set the transaction rollback-only. This instructs the transaction manager 
  15.      * that the only possible outcome of the transaction may be a rollback, as 
  16.      * alternative to throwing an exception which would in turn trigger a rollback. 
  17.      */  
  18.     void setRollbackOnly();  
  19.     /** 
  20.      * Return whether the transaction has been marked as rollback-only 
  21.      * (either by the application or by the transaction infrastructure). 
  22.      */  
  23.     boolean isRollbackOnly();  
  24.     /** 
  25.      * Flush the underlying session to the datastore, if applicable: */  
  26.     void flush();  
  27.     /** 
  28.      * Return whether this transaction is completed, that is, 
  29.      * whether it has already been committed or rolled back.     */  
  30.     boolean isCompleted();  
  31. }  
 

编程事务管理举例:

[java] view plaincopy
  1. public class TransactionDAO {  
  2.     private JdbcTemplate jdbcTemplate;  
  3.     private DataSourceTransactionManager transactionManager;  
  4.     private DefaultTransactionDefinition def;  
  5.       
  6.     public void setDataSource(DataSource dataSource){  
  7.         jdbcTemplate=new JdbcTemplate(dataSource);  
  8.         transactionManager=  
  9.             new DataSourceTransactionManager(dataSource);  
  10.         def=new DefaultTransactionDefinition();  
  11.         def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);  
  12.     }  
  13.       
  14.     public void insert(User user){  
  15.         TransactionStatus status=  
  16.             transactionManager.getTransaction(def);  
  17.         try{  
  18.             jdbcTemplate.update("insert into user(name) values('"+user.getName()+"')");  
  19.             jdbcTemplate.update("insert");  
  20.         }catch(DataAccessException e){  
  21.             transactionManager.rollback(status);  
  22.             throw e;  
  23.         }  
  24.         transactionManager.commit(status);  
  25.     }  
  26. }  
 

声明事务管理:

声明式事务管理依赖它的AOP框架,使用它只需在定义文件中进行配置,事务管理不会侵入所开发的组件,而且便于修改。简单的Bean定义文件配置如下:

[java]  view plain copy
  1. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  2.     <property name="dataSource" ref="dataSource"></property>  
  3. </bean>  
  4. <bean id="userDAO" class="org.spring.dao.UserDAO">  
  5.     <property name="dataSource" ref="dataSource"></property>  
  6. </bean>  
  7. <bean id="userDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">  
  8.     <property name="proxyInterfaces">  
  9.         <list>  
  10.             <value>org.spring.dao.IUserDAO</value>  
  11.         </list>  
  12.     </property>  
  13.     <property name="target" ref="userDAO"></property>  
  14.     <property name="transactionManager" ref="transactionManager"></property>  
  15.     <property name="transactionAttributes">  
  16.         <props>  
  17.             <prop key="insert*">PROPAGATION_REQUIRED</prop>  
  18.         </props>  
  19.     </property>  
  20. </bean>  
 

transactionManager、userDAO使用同一个DataSource,在org.springframework.transaction.interceptor.TransactionProxyFactoryBean代理对象中设置被代理接口、被代理目标实例、事务管理器以及事务属性。这样事务管理会自动介入指定的方法前后。如上,userDAO中以insert开头的方法都会被纳入事务管理,即方法执行过程中发生错误,则方法中所有先前的操作都自动撤回,否则正常提交。

事务属性可以在TransactionDefinition接口中找到。对于目标方法可以加上多个事务属性定义,中间用","隔开。

这样配置后,就可以正常使用UserDAO了,在UserDAO类中不需要增加事务管理代码。即

IUserDAO dao=(IUserDAO)context.getBean("userDAOProxy");dao.insert(user);

也可以设置单独的Interceptor,如下:

[java]  view plain copy
  1. <bean id="transactionInterceptor"   
  2.     class="org.springframework.transaction.interceptor.TransactionInterceptor">  
  3.     <property name="transactionManager" ref="transactionManager"/>  
  4.     <property name="transactionAttributeSource"   
  5.     value="org.spring.dao.UserDAO.insert*=PROPAGATION_REQUIRED"/>  
  6. </bean>  
  7. <bean id="userDAOProxy1"   
  8.     class="org.springframework.aop.framework.ProxyFactoryBean">  
  9.     <property name="proxyInterfaces">  
  10.         <list>  
  11.             <value>org.spring.dao.IUserDAO</value>  
  12.         </list>  
  13.     </property>  
  14.     <property name="target" ref="userDAO"></property>  
  15.     <property name="interceptorNames">  
  16.         <list>  
  17.             <value>transactionInterceptor</value>  
  18.         </list>  
  19.     </property>  
  20. </bean>  
 

总结:Spring的学习笔记就到此结束了,基本内容概括的差不多了。随着学习和应用,会对Spring进行深层的补充和理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值