加入收藏 | 设为首页 | 会员中心 | 我要投稿 开发网_开封站长网 (http://www.0378zz.com/)- 科技、AI行业应用、媒体智能、低代码、办公协同!
当前位置: 首页 > 教程 > 正文

Spring中事务管理畅聊

发布时间:2021-11-24 16:51:46 所属栏目:教程 来源:互联网
导读:Spring中对事务的声明式管理 拿一个XML举例 [html] ?xml version=1.0 encoding=UTF-8? beans xmlns=http://www.springframework.org/schema/beans xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:aop=http://www.springframework.org/schema/ao

Spring中对事务的声明式管理
拿一个XML举例
 
[html]
<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xmlns:aop="http://www.springframework.org/schema/aop"  
       xmlns:tx="http://www.springframework.org/schema/tx"  
       xsi:schemaLocation="  
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd  
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">  
  
  
  事务管理目标Service  
  <bean id="fooService" class="x.y.service.DefaultFooService"/>  
    
  切面配置,配置了切入点是执行FooService下的所有方法 和 切入点调用的通知器为txAdvice  
  <aop:config>  
    <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>  
    <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>  
  </aop:config>  
    
  该通知器的具体配置,所使用的事务管理器,所配置的事务规则  
  <tx:advice id="txAdvice" transaction-manager="txManager">  
    <!-- the transactional semantics... -->  
      
    <tx:attributes>  
      <!-- all methods starting with 'get' are read-only -->  
        
      <tx:method name="get*" read-only="true"/>  
      <!-- other methods use the default transaction settings (see below) -->  
        
      <tx:method name="*"/>  
    </tx:attributes>  
  </tx:advice>  
  
  所选用的事务管理器,和作为启动参数塞入的dataSource  
  <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
    <property name="dataSource" ref="dataSource"/>  
  </bean>  
  
  
  连接数据库的dataSource  
  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
    <property name="driverClassName" value="Oracle.jdbc.driver.OracleDriver"/>  
    <property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"/>  
    <property name="username" value="scott"/>  
    <property name="password" value="tiger"/>  
  </bean>  
    
</beans>  
Spring中对事务管理的底层实现
以上的方法,选用了Spring本身自带的JDBC的事务控制器做处理。
 
相关代码集中在DataSourceTransactionManager中
 
比如,事务的取得并且将取得的事务捆绑进当前线程中
 
[Java]
@Override  
    protected Object doGetTransaction() {  
        DataSourceTransactionObject txObject = new DataSourceTransactionObject();  
        txObject.setSavepointAllowed(isNestedTransactionAllowed());  
        ConnectionHolder conHolder =  
            (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);  
        txObject.setConnectionHolder(conHolder, false);  
        return txObject;  
    }  
在比如事务的开始,
 
[java]
/**
     * This implementation sets the isolation level but ignores the timeout.
     */  
    @Override  
    protected void doBegin(Object transaction, TransactionDefinition definition) {  
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
        Connection con = null;  
  
        try {  
            if (txObject.getConnectionHolder() == null ||  
                    txObject.getConnectionHolder().isSynchronizedWithTransaction()) {  
                Connection newCon = this.dataSource.getConnection();  
                if (logger.isDebugEnabled()) {  
                    logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");  
                }  
                txObject.setConnectionHolder(new ConnectionHolder(newCon), true);  
            }  
  
            txObject.getConnectionHolder().setSynchronizedWithTransaction(true);  
            con = txObject.getConnectionHolder().getConnection();  
  
            Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);  
            txObject.setPreviousIsolationLevel(previousIsolationLevel);  
  
            // Switch to manual commit if necessary. This is very expensive in some JDBC drivers,   
            // so we don't want to do it unnecessarily (for example if we've explicitly   
            // configured the connection pool to set it already).   
            if (con.getAutoCommit()) {  
                txObject.setMustRestoreAutoCommit(true);  
                if (logger.isDebugEnabled()) {  
                    logger.debug("Switching JDBC Connection [" + con + "] to manual commit");  
                }  
                con.setAutoCommit(false);  
            }  
            txObject.getConnectionHolder().setTransactionActive(true);  
  
            int timeout = determineTimeout(definition);  
            if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {  
                txObject.getConnectionHolder().setTimeoutInSeconds(timeout);  
            }  
  
            // Bind the session holder to the thread.   
            if (txObject.isNewConnectionHolder()) {  
                TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());  
            }  
        }  
  
        catch (Exception ex) {  
            DataSourceUtils.releaseConnection(con, this.dataSource);  
            throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);  
        }  
    }  
等等这里就不多说了,起个头

(编辑:开发网_开封站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读