<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 156,  comments - 601,  trackbacks - 0

    前言:
      如果大家使用過Spring事務管理,會發(fā)現(xiàn)Spring提供的事務分為“只讀”和“讀寫”事務兩類。這不免就會疑問這兩種事務會有什么不同?本文則通過對Spring和Hibernate源代碼的剖析來找出這兩種事務的區(qū)別。特別是運行性能方面的區(qū)別。
      解讀的源代碼版本為 Spring 2.5.6.SEC01 ,Hibernate 3.3.2.GA。

      Spring對事務的支持也分編程式和聲明式,本文以基于Annotation方式的聲明式事務為例:
     
      Spring的配置如下:
        <bean
            
    class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
            
    <property name="proxyTargetClass" value="true"></property>
        
    </bean>
        
    <bean id="entityManagerFactory"
            class
    ="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
            
    <property name="persistenceUnitName" value="entityManager" />
            
    <property name="jpaProperties">
                
    <props>
                
    </props>
            
    </property>
        
    </bean>

        
    <bean id="transactionManager"
            class
    ="org.springframework.orm.jpa.JpaTransactionManager">
            
    <property name="entityManagerFactory" ref="entityManagerFactory" />
        
    </bean>
        
    <bean id="transactionInterceptor"
            class
    ="org.springframework.transaction.interceptor.TransactionInterceptor">
            
    <property name="transactionManager" ref="transactionManager" />
            
    <property name="transactionAttributeSource">
                
    <bean
                    
    class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource" />
            
    </property>
        
    </bean>
        
    <bean id="transactionAttributeSourceAdvisor"
            class
    ="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
            
    <property name="transactionInterceptor"    ref="transactionInterceptor" />
        
    </bean>

    從配置中,可以看到事務的攔截,都由 TransactionInterceptor 類進行處理
    下面是invoke方法的核心處理過程:

        public Object invoke(final MethodInvocation invocation) throws Throwable {
            
    // Work out the target class: may be <code>null</code>.
            
    // The TransactionAttributeSource should be passed the target class
            
    // as well as the method, which may be from an interface.
            Class targetClass = (invocation.getThis() != null ? invocation.getThis().getClass() : null);

            
    // If the transaction attribute is null, the method is non-transactional.
            final TransactionAttribute txAttr =
                    getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass);
            
    final String joinpointIdentification = methodIdentification(invocation.getMethod());

            
    if (txAttr == null || !(getTransactionManager() instanceof CallbackPreferringPlatformTransactionManager)) {
                
    // Standard transaction demarcation with getTransaction and commit/rollback calls.
                TransactionInfo txInfo = createTransactionIfNecessary(txAttr, joinpointIdentification);
                Object retVal 
    = null;
                
    try {
                    
    // This is an around advice: Invoke the next interceptor in the chain.
                    
    // This will normally result in a target object being invoked.
                    retVal = invocation.proceed();
                }
                
    catch (Throwable ex) {
                    
    // target invocation exception
                    completeTransactionAfterThrowing(txInfo, ex);
                    
    throw ex;
                }
                
    finally {
                    cleanupTransactionInfo(txInfo);
                }
                
    //處理事務的操作
                commitTransactionAfterReturning(txInfo);
                
    return retVal;
            }
            .省略
        }

    針對事務的操作,就是調用 commitTransactionAfterReturning 方法進行事務的處理。
    該方法會調用AbstractPlatformTransactionManager類的commit和processCommit方法。processCommit方法是真正調用Hibernate事務處理的實現(xiàn)。

        private void processCommit(DefaultTransactionStatus status) throws TransactionException {
            
    try {
                
    boolean beforeCompletionInvoked = false;
                
    try {
                    prepareForCommit(status);
                    triggerBeforeCommit(status);
                    triggerBeforeCompletion(status);
                    beforeCompletionInvoked 
    = true;
                    
    boolean globalRollbackOnly = false;
                    
    if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
                        globalRollbackOnly 
    = status.isGlobalRollbackOnly();
                    }
                    
    if (status.hasSavepoint()) {
                        
    if (status.isDebug()) {
                            logger.debug(
    "Releasing transaction savepoint");
                        }
                        status.releaseHeldSavepoint();
                    }
                    
    else if (status.isNewTransaction()) { //如果是一個新啟的事務
                        if (status.isDebug()) {
                            logger.debug(
    "Initiating transaction commit");
                        }
    //則進行事務的提交處理
                        doCommit(status);
                    }
                 代碼省略
        }

    doCommit 方法的調用 會觸發(fā) Hibernate的JDBCTransaction的commit方法調用

        public void commit() throws HibernateException {
            
    if (!begun) {
                
    throw new TransactionException("Transaction not successfully started");
            }

            log.debug(
    "commit");
            
    //如果是只讀事務,Spring會將transactionContext的 isFlushModeNever 設置為true
            if ( !transactionContext.isFlushModeNever() && callback ) {
              
    //刷新一級緩存中的持久對象,向數(shù)據(jù)庫發(fā)送sql語句  
                transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
            }

            notifyLocalSynchsBeforeTransactionCompletion();
            
    if ( callback ) {
                jdbcContext.beforeTransactionCompletion( 
    this );
            }

            
    try {
                commitAndResetAutoCommit();
                log.debug(
    "committed JDBC Connection");
                committed 
    = true;
                
    if ( callback ) {
                    jdbcContext.afterTransactionCompletion( 
    truethis );
                }
                notifyLocalSynchsAfterTransactionCompletion( Status.STATUS_COMMITTED );
            }
            
    catch (SQLException e) {
                log.error(
    "JDBC commit failed", e);
                commitFailed 
    = true;
                
    if ( callback ) {
                    jdbcContext.afterTransactionCompletion( 
    falsethis );
                }
                notifyLocalSynchsAfterTransactionCompletion( Status.STATUS_UNKNOWN );
                
    throw new TransactionException("JDBC commit failed", e);
            }
            
    finally {
                closeIfRequired();
            }
        }   

    關鍵點已經在上面的注釋中說明。
    當事務被標識為只讀事務時,Spring可以對某些可以針對只讀事務進行優(yōu)化的資源就可以執(zhí)行相應的優(yōu)化措施,上面Spring告之hibernate的session在只讀事務模式下不用嘗試檢測和同步持久對象的狀態(tài)的更新。


    總結:
      如果在使用事務的情況下,所有操作都是讀操作,那建議把事務設置成只讀事務,或者事務的傳播途徑最好能設置為 supports (運行在當前的事務范圍內,如果當前沒有啟動事務,那么就不在事務范圍內運行)或者 not supports (不在事務范圍內執(zhí)行,如果當前啟動了事務,那么掛起當前事務),這樣不在事務下,就不會調用transactionContext.managedFlush(); 方法。
    所有只讀事務與讀寫事務的比較大的運行性能區(qū)別就是只讀事務避免了Hibernate的檢測和同步持久對象的狀態(tài)的更新,提升了運行性能。

    Good Luck!
    Yours Matthew!



    posted on 2010-05-06 19:31 x.matthew 閱讀(6058) 評論(1)  編輯  收藏 所屬分類: Spring|Hibernate|Other framework
    主站蜘蛛池模板: 亚洲AV无码精品国产成人| 最好看最新的中文字幕免费| 国产精品亚洲午夜一区二区三区| 亚洲性在线看高清h片| 欧美最猛性xxxxx免费| 暖暖日本免费中文字幕| 日日狠狠久久偷偷色综合免费 | 亚洲一区精品无码| 日韩毛片免费在线观看| 4455永久在线观免费看| 日韩av无码免费播放| 人体大胆做受免费视频| 色窝窝亚洲AV网在线观看| 亚洲国产成人精品久久| 亚洲短视频男人的影院| 亚洲宅男天堂在线观看无病毒| 国产在线观看www鲁啊鲁免费| 日本成年免费网站| 84pao国产成视频免费播放| 成人无码a级毛片免费| 成人免费777777被爆出| 色老头综合免费视频| 美女被艹免费视频| 亚洲精品又粗又大又爽A片| 亚洲看片无码在线视频| 亚洲国产中文在线视频| 亚洲日本国产精华液| 亚洲黄色免费网站| 亚洲视频一区在线观看| 亚洲的天堂av无码| 亚洲精品国产手机| 亚洲制服丝袜一区二区三区| 亚洲日产2021三区| 亚洲xxxxxx| 亚洲精品女同中文字幕| 久久亚洲精品无码av| 国产成人va亚洲电影| 成人a毛片免费视频观看| 又硬又粗又长又爽免费看| 一级做a爰片性色毛片免费网站| 亚欧乱色国产精品免费视频|