Spring transaction management implementation

There are two ways of Spring's transaction management: one is the traditional programmatic transaction management, that is, the transaction management realized by writing code; the other is the declarative transaction management based on AOP technology. Since programmatic transaction management is rarely used in actual development, we will only explain Spring's declarative transaction management in detail.

The following is a detailed explanation of transaction implementation from the data access method:

    <!-- 加载配置文件 数据源db.properties -->
	<context:property-placeholder location="classpath:config/db.properties"/>

	<!-- 数据源配置,使用数据库连接池druid -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
		init-method="init" destroy-method="close">
		<!-- 数据库驱动 -->
		<property name="driverClassName" value="${jdbc.driver}" /> 
		<!-- 基本属性 url、user、password -->
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<!-- 配置初始化大小、最小、最大 -->
		<property name="initialSize" value="1" />
		<property name="minIdle" value="1" />
		<property name="maxActive" value="20" />
		<!-- 配置获取连接等待超时的时间 -->
		<property name="maxWait" value="60000" />
		<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
		<property name="minEvictableIdleTimeMillis" value="300000" />
		<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
		<property name="poolPreparedStatements" value="true" />
		<property name="maxPoolPreparedStatementPerConnectionSize"
			value="20" />
		<!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计   记录日志-->
		<property name="filters" value="stat,slf4j" />
	</bean>

JDBC transaction management implementation: 

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"/>	
</bean>

Mybatis transaction management implementation: 

<!-- spring集成mybatis集中管理session -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- 引入数据源 -->
		<property name="dataSource" ref="dataSource"/>
		<!-- 加载mybatis核心配置文件-->
		<property name="configlocation" value="classpath:config/mybatis.cfg.xml"/>
		<!-- 批量别名定义,自动扫描包,自动定义别名,别名就是类名(首字母大写或小写都可以) -->
		<!-- <property name="typeAliasesPackage" value="com.huayuan.bean"></property> -->
		<!-- 扫描sql配置文件,mapper.xml -->
		<!-- <property name="mapperLocations" value="classpath:com/huayuan/mapper/*.xml"></property> -->
	</bean>

	<!-- 配置Ibatis的事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>	
	</bean>

Hibernate transaction management implementation: 

<!-- 配置hibernate的sessionFactory -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
			</props>
		</property>
		<property name="mappingResources">
			<list>
				<value>com/hisu/beans/User.hbm.xml</value>
			</list>
		</property>	
	</bean>           
	

The following is a general method to implement transactions:

1. Each Bean has a proxy: 

<!-- 配置DAO -->
    <bean id="userDAO" class="com.hisu.DAOImpl.UserDAOImpl" scope="singleton">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    <bean id="userDAOProxy"  
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" lazy-init="true" abstract="true">
    
         <property name="transactionManager" ref="transactionManager" /> 
    
          <property name="target" ref="userDAO" />

          <!-- 配置事务属性 -->  
        <property name="transactionAttributes">  
            <props>  
                <prop key="insert*">PROPAGATION_REQUIRED</prop>
                <prop key="update*">PROPAGATION_REQUIRED</prop>
                <prop key="delete*">PROPAGATION_REQUIRED</prop>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
            </props>  
        </property>  
    </bean>

Second, all beans share a proxy base class: 

<bean id="transactionBase"  
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" lazy-init="true" abstract="true">
    
         <property name="transactionManager" ref="transactionManager" />

          <!-- 配置事务属性 -->  
        <property name="transactionAttributes">  
            <props>  
                <prop key="insert*">PROPAGATION_REQUIRED</prop>
                <prop key="update*">PROPAGATION_REQUIRED</prop>
                <prop key="delete*">PROPAGATION_REQUIRED</prop>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
            </props>  
        </property>  
    </bean> 

	<!-- 配置DAO -->
    <bean id="userDAO" class="com.hisu.DAOImpl.UserDAOImpl" parent="transactionBase" scope="singleton">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean> 

Third, use the interceptor:

<bean id="transactionInterceptor"  
        class="org.springframework.transaction.interceptor.TransactionInterceptor" lazy-init="true" abstract="true">
    
         <property name="transactionManager" ref="transactionManager" />

          <!-- 配置事务属性 -->  
        <property name="transactionAttributes">  
            <props>  
                <prop key="insert*">PROPAGATION_REQUIRED</prop>
                <prop key="update*">PROPAGATION_REQUIRED</prop>
                <prop key="delete*">PROPAGATION_REQUIRED</prop>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
            </props>  
        </property>  
    </bean>

	<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">  
        <property name="beanNames">  
            <list>  
                <value>com.hisu.dao.*</value>
            </list>  
        </property>  
        <property name="interceptorNames">  
            <list>  
                <value>transactionInterceptor</value>  
            </list>  
        </property>  
    </bean>

4. Interceptors configured with tx tags: (recommended) 

<!-- 配置事务的传播特性 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED"/>
			<tx:method name="delete*" propagation="REQUIRED"/>
			<tx:method name="modify*" propagation="REQUIRED"/>
			<tx:method name="*" read-only="true"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 那些类的哪些方法参与事务 -->
	<aop:config>
		<aop:advisor pointcut="execution(* com.evan.crm.service.*.*(..))" advice-ref="txAdvice"/>
	</aop:config>

 (* com.evan.crm.service. *. * (..)) The meaning of several wildcards:

The first *
-any wildcard return value type The second *-any class under the wildcard package com.evan.crm.service The
third *-the wildcard package com.evan.crm.service Any method of any class. The
fourth ..-The wildcard method can have 0 or more parameters

Five, full annotations (automatically handle interfaces, classes, methods marked "@Transaction")  

<tx:annotation-driven transaction-manager="transactionManager"/>

 

Published 203 original articles · won praise 6 · views 4495

Guess you like

Origin blog.csdn.net/weixin_42073629/article/details/105354388