溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Spring中@Transactional如何配置

發(fā)布時(shí)間:2021-12-20 10:54:49 來(lái)源:億速云 閱讀:378 作者:小新 欄目:互聯(lián)網(wǎng)科技

這篇文章將為大家詳細(xì)講解有關(guān)Spring中@Transactional如何配置,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

  • 背景:

    1. spring老版本是使用TransactionProxyFactoryBean來(lái)實(shí)現(xiàn)對(duì)spring的事務(wù)進(jìn)行配置(缺點(diǎn)自己google,一大堆的缺點(diǎn))

    2. spring2.x引入了AOP(面向切面的編程)

    3. 當(dāng)初項(xiàng)目也是喜歡用spring xml方式的配置,后來(lái)項(xiàng)目使用spring3.x版本,看到了@Transactional注解,個(gè)人覺(jué)得挺方便和實(shí)用。(具體什么原因,說(shuō)不清)

  • 上代碼

    1. <?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:context="http://www.springframework.org/schema/context"
             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-3.2.xsd
      		     http://www.springframework.org/schema/context
      		     http://www.springframework.org/schema/context/spring-context-3.2.xsd
      		     http://www.springframework.org/schema/tx
      		     http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
      		     http://www.springframework.org/schema/aop 
      		     http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
      
      
          <!-- ################# start ################ -->
      
          <context:component-scan base-package="com.xun.spring3.src"></context:component-scan>
      
          <bean id="placeholderConfig"
                class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
              <property name="location">
                  <value>classpath:/db.properties</value>
              </property>
          </bean>
      
          <!-- ################### end ############## -->
      
      	<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
      		<property name="dataSource" ref="dataSource"></property>
      		<property name="configLocation">
      			<value>classpath:/sqlmap-config.xml</value>
      		</property>
      		<property name="mappingLocations">
      			<value>classpath*:/sqlmap/*.xml</value>
      		</property>
      	</bean>
      
          <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
                init-method="init" destroy-method="close">
              <property name="url" value="${jdbc.url}" />
              <property name="username" value="${jdbc.user}"></property>
              <property name="password" value="${jdbc.password}" />
      
              <property name="filters"><value>stat</value></property>
      
              <property name="maxActive"><value>20</value></property>
              <property name="initialSize"><value>1</value></property>
              <property name="maxWait"><value>60000</value></property>
              <property name="minIdle"><value>1</value></property>
      
              <property name="timeBetweenEvictionRunsMillis"><value>60000</value></property>
              <property name="minEvictableIdleTimeMillis"><value>300000</value></property>
      
              <property name="validationQuery"><value>SELECT 'x'</value></property>
              <property name="testWhileIdle"><value>true</value></property>
              <property name="testOnBorrow"><value>false</value></property>
              <property name="testOnReturn"><value>false</value></property>
      
              <property name="poolPreparedStatements"><value>true</value></property>
              <property name="maxOpenPreparedStatements"><value>20</value></property>
          </bean>
      
          <!--
              其實(shí) 不涉及到分布式事務(wù)的話,無(wú)需定義這個(gè)模板 sqlMapClient,因?yàn)閎asedao已經(jīng)SqlMapClientDaoSupport這個(gè)類,
              SqlMapClientDaoSupport中已經(jīng)有SqlMapClientTemplate這個(gè)屬性了。
          -->
          <!--
          <bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
              <property name="sqlMapClient" ref="sqlMapClient"></property>
          </bean>
          -->
      
      	<!-- transaction confige -->
          <!--
              作用:開啟對(duì)@Transactional注解的加工處理,以織入事務(wù)管理切面
              <tx:annotation-driven>屬性說(shuō)明:
              (1):屬性transaction-manager:指定事務(wù)管理器名字,默認(rèn)為transactionManager,當(dāng)使用其他名字時(shí)需要明確指定
              (2):proxy-target-class: 如果為true,Spring將通過(guò)創(chuàng)建子類來(lái)代理業(yè)務(wù)類;
                                      如果為false(默認(rèn)),則使用基于接口來(lái)代理。
                                      (ps:如果使用子類代理,需要在類路徑中添加CGLib.jar類庫(kù))
              (3):order:如果業(yè)務(wù)類除事務(wù)切面外,還需要織入其它的切面(或者多個(gè)事務(wù)切面),通過(guò)該屬性來(lái)控制切面在目標(biāo)連接點(diǎn)的織入順序
          -->
      	<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />
      
          <!--proxy-target-class:默認(rèn)false表示使用JDK代理,如果為true將使用CGLIB代理-->
          <!-- 使用CGLIB的話需要加上aspectjrt和aspectjweaver 的jar-->
          <aop:aspectj-autoproxy proxy-target-class="true" />
      
          <!-- 對(duì)于cobar對(duì)數(shù)據(jù)源的時(shí)候我們用這個(gè) -->
          <!--<bean id="txManager" class="com.alibaba.cobar.client.transaction.MultipleDataSourcesTransactionManager">
      		<property name="cobarDataSourceService" ref="dataSources" />
          </bean>-->
          <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
              <property name="dataSource" ref="dataSource"></property>
          </bean>
      
      </beans>
    2. package com.xun.spring3.src.dao;
      
      import com.ibatis.sqlmap.client.SqlMapClient;
      import org.apache.commons.lang.StringUtils;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
      
      import javax.annotation.PostConstruct;
      import java.lang.reflect.ParameterizedType;
      import java.lang.reflect.Type;
      
      /**
       * 要求每個(gè)dao的命名以 Dao結(jié)尾
       * 泛型 ENTITY - 具體哪個(gè)實(shí)體
       * 泛型 PRIMARYKEY - 具體主鍵的類型
       * @Date : 2014/9/7 0007 20:41
       * @From : spring3-test
       * @Author : hebad90@163.com
       */
      public class BaseDao<ENTITY, PRIMARYKEY> extends SqlMapClientDaoSupport {
      
          @Autowired
          private SqlMapClient sqlMapClient;
      
          @PostConstruct
          private void initSuper() {
              /**
               * 初始化父類
               */
              super.setSqlMapClient( sqlMapClient );
          }
      
          private Class entityClass ;
      
          private String ibatisNamespace;
      
          protected BaseDao() {
              Type genType = getClass().getGenericSuperclass();
              Type[] params = ((ParameterizedType)genType).getActualTypeArguments();
              entityClass = (Class)params[0];
      
              /**
               * 獲取當(dāng)前 ibatis的命名空間 XxxDao 即命名空間為 xxx
               */
              this.ibatisNamespace = getIbatisNamespace( getClass() );
      
              System.out.println( "初始化當(dāng)前環(huán)境成功,ibatisNamespace=["+this.ibatisNamespace+"],entityClass=[" + entityClass + "]" );
      
          }
      
          public PRIMARYKEY insert( ENTITY entity ) {
              return(PRIMARYKEY)super.getSqlMapClientTemplate().insert( this.ibatisNamespace + ".insert", entity );
          }
      
          public int update( ENTITY entity ) {
              return super.getSqlMapClientTemplate().update( this.ibatisNamespace + ".update", entity );
          }
      
          public ENTITY queryById( PRIMARYKEY primarykey ) {
              return ( ENTITY ) super.getSqlMapClientTemplate().queryForObject( this.ibatisNamespace + ".queryById", primarykey);
          }
      
          public int delete( ENTITY entity ) {
              return super.getSqlMapClientTemplate().delete( this.ibatisNamespace + ".delete", entity);
          }
      
      
          ///##############################
          private String getIbatisNamespace( Class clazz ) {
              String simpleName = clazz.getSimpleName();
              int index = StringUtils.indexOf( simpleName, "Dao" );
      
              return StringUtils.lowerCase( StringUtils.substring( simpleName, 0, index ) );
          }
      
      }
    3. @Transactional在何處使用?Spring建議我們?cè)跇I(yè)務(wù)實(shí)現(xiàn)類上使用該注解,因?yàn)閖ava的實(shí)現(xiàn)不能繼承注解。所以,最好是在業(yè)務(wù)實(shí)現(xiàn)類上注解,這樣不管<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />中的proxy-target-class為true或者false,業(yè)務(wù)類都會(huì)啟用事務(wù)機(jī)制。

    4. @Transactional的參數(shù)怎么使用?Spring中@Transactional如何配置




關(guān)于“Spring中@Transactional如何配置”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI