Sping事务管理

   

事务: 

逻辑上的一组操作,要么全发生,要么全不发生。

事务特性:

 一.原子性   二.一致性   三.隔离性   四.持久性

Sping事务管理:  

 编程式事务管理和声明式事务管理

编程式事务管理: 

Sping提供 DataSourceTransactionManager和 TransactionTemplate事务管理器模版 类完成业务逻辑事务管理操作,可以直接在.xml配置:

核心配置:


<!-- 启用@AsjectJ支持 -->
	<aop:aspectj-autoproxy />
   	<bean id="accountService" class="com.spring.transaction.demo1.AccountServiceImpl">
   		 <property name="accountDao" ref="accountDao"></property>  
   	</bean>  
 
    <bean id="accountDao" class="com.spring.transaction.demo1.AccountDaoImpl">
    	 <!-- 将模版注入到AccountDaoImpl -->
    	 <property name="jdbcTemplate" ref="jdbcTemplate"></property>  
    </bean>
    <!--  传统方法配置数据源 -->
   	<bean id="dataSource"  class="org.apache.commons.dbcp.BasicDataSource">  
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
       	<!--  注意一下&characterEncoding要修改为&characterEncoding   -->
    	<property name="url" value="jdbc:mysql://localhost:3306/pager"/>        
        <property name="username" value="root"/>  
        <property name="password" value="666123" />  
    </bean>
    
    <!--配置jdbcTemplate(以创建一个jdbc模版,当然也可以继承JdbcDaoSupport获得模版) -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    	<!-- 将连接池注入到JdbcTemplate(获得连接) -->
        <property name="dataSource" ref="dataSource"></property>
    </bean> 
    
    <!--配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    	<!-- 将连接池注入到transactionManager -->
        <property name="dataSource" ref="dataSource"></property>
    </bean> 
    
    <!--配置事务管理器模版:Spring为简化事务管理的代码而提供的类 -->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    	<!-- 将事务管理器注入模版-->
        <property name="transactionManager" ref="transactionManager"></property>
    </bean> 
    



声明式事务管理:只需要为Spring添加配置(XML/Annotation开启注解),就可以为目标代码(service)添加事务管理功能.

Spring事务管理高层抽象主要由PlatformTransactionManager/TransactionDefinition/TransactionStatus三个接口提供支持



事务 描述
DataSourceTransactionManager JDBCTemplate/MyBatis/iBatis持久化使用
HibernateTransactionManager Hibernate持久化使用
JpaTransactionManager JPA持久化使用
JdoTransactionManager JDO持久化使用
JtaTransactionManager JTA实现管理事务,一个事务跨越多个资源时使用

因此使用Spring管理事务,需要为不同持久层配置不同事务管理器实现.



TransactionDefinition(事务定义信息):

TransactionDefinition提供了对事务的相关配置, 如事务隔离级别/传播行为/只读/超时等:

  • 隔离级别(isolation) 
    为解决事务并发引起的问题(脏读/幻读/不可重复读),引入四个隔离级别:
隔离级别 描述
DEFAULT 使用数据库默认的隔离级别
READ_UNCOMMITED 读未提交
READ_COMMITTED 读已提交(Oracle默认)
REPEATABLE_READ 可重复读(MySQL默认)
SERIALIZABLE 串行化

关于事务隔离级别的讨论, 可参考我的博客JDBC基础-事务隔离级别部分.


传播行为(propagation) :

传播行为不是数据库的特性, 而是为了在业务层解决两个事务相互调用的问题:

传播类型 描述
REQUIRED 支持当前事务,如果不存在就新建一个(默认)
SUPPORTS 支持当前事务,如果不存在就不使用事务
MANDATORY 支持当前事务,如果不存在则抛出异常
REQUIRES_NEW 如果有事务存在,则挂起当前事务新建一个
NOT_SUPPORTED 以非事务方式运行,如果有事务存在则挂起当前事务
NEVER 以非事务方式运行,如果有事务存在则抛出异常
NESTED 如果当前事务存在,则嵌套事务执行(只对DataSourceTransactionManager有效)
  • 超时时间(timeout)
  • 只读(read-only) 
    只读事务, 不能执行INSERT/UPDATE/DELETE操作.


TransactionStatus(事务状态信息):


获得事务执行过程中某一个时间点状态.



声明式事务管理的实现:

1.传统方法,基于TransactionProxyFactoryBean的方式

2.基于AspectJ的XML配置的实现方式

3.基于注解的实现方式

1.基于TransactionProxyFactoryBean的方式:


核心配置:

	<!-- 启用@AsjectJ支持 -->
	<aop:aspectj-autoproxy />
   	<bean id="accountService" class="com.spring.transaction.demo2.AccountServiceImpl">
   		 <property name="accountDao" ref="accountDao"></property>  
   	</bean>  
 
    <bean id="accountDao" class="com.spring.transaction.demo2.AccountDaoImpl">
    	 <!-- 将模版注入到AccountDaoImpl,这时jdbcTemplate已被Spring增强-->
    	 <property name="jdbcTemplate" ref="jdbcTemplate"></property>  
    </bean>
    <!--  传统方法配置数据源 -->
   	<bean id="dataSource"  class="org.apache.commons.dbcp.BasicDataSource">  
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
       	<!--  注意一下&characterEncoding要修改为&characterEncoding   -->
    	<property name="url" value="jdbc:mysql://localhost:3306/pager"/>        
        <property name="username" value="root"/>  
        <property name="password" value="666123" />  
    </bean>
    
    <!--配置jdbcTemplate(以创建一个jdbc模版,当然也可以继承JdbcDaoSupport获得模版) -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    	<!-- 将连接池注入到JdbcTemplate(获得连接) -->
        <property name="dataSource" ref="dataSource"></property>
    </bean> 
    
     <!--配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean> 
    
    <!--配置业务层的代理 -->
    <bean id="serviceProxyFactoryBean" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    	<property name="proxyInterfaces">  
  			 <!-- 至少一个接口(创建的代理对象和目标对象都要实现这些接口) -->  
    		<list>  
     			<value>com.spring.transaction.demo2.AccountService</value>  
    		</list>  
   		</property>  
    	<!-- 配置目标对象-->
    	 <property name="target" ref="accountService"></property>
    	<!-- 注入事务管理器-->
        <property name="transactionManager" ref="transactionManager"></property>
        <!-- 注入事务属性-->
        <property name="transactionAttributes" >
        	<props>
        		<!--ISOLATION_:
        			readyOnly:
        			-Exception:
        			+Exception: -->
        		<prop key="transfer">PROPAGATION_REQUIRED</prop>
        	</props>
        </property>
    </bean> 

注意:

注入accountService时,name=“serviceProxyFactoryBean”,因为accountService Bean在serviceProxyFactoryBean中已被增强。

即,


@Resource(name="serviceProxyFactoryBean")
private AccountService accountService;


2.基于AspectJ的XML配置的实现方式:


核心思想:

AOP面向切面编程

在<aop:advisor>中引入在标签中配置 好的事务管理器<tx:advice>通知	
<-- 启用@AsjectJ支持 -->
	<aop:aspectj-autoproxy />
   	<bean id="accountService" class="com.spring.transaction.demo3.AccountServiceImpl">
   		 <property name="accountDao" ref="accountDao"></property>  
   	</bean>  
 
    <bean id="accountDao" class="com.spring.transaction.demo3.AccountDaoImpl">
    	 <!-- 将模版注入到AccountDaoImpl,这时jdbcTemplate已被Spring增强-->
    	 <property name="jdbcTemplate" ref="jdbcTemplate"></property>  
    </bean>
    <!--  传统方法配置数据源 -->
   	<bean id="dataSource"  class="org.apache.commons.dbcp.BasicDataSource">  
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
       	<!--  注意一下&characterEncoding要修改为&characterEncoding   -->
    	<property name="url" value="jdbc:mysql://localhost:3306/pager"/>        
        <property name="username" value="root"/>  
        <property name="password" value="666123" />  
    </bean>
    
    <!--配置jdbcTemplate(以创建一个jdbc模版,当然也可以继承JdbcDaoSupport获得模版) -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    	<!-- 将连接池注入到JdbcTemplate(获得连接) -->
        <property name="dataSource" ref="dataSource"></property>
    </bean> 
    
     <!--配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean> 
    
    <!--配置事务的通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
	    <!-- 定义方法的过滤规则 -->
	    <tx:attributes>
	        <tx:method name="transfer"  propagation="REQUIRED" read-only="false"/>
	    </tx:attributes>
	 </tx:advice>
    
    <aop:config>
     	<aop:pointcut expression="execution(* com.spring.transaction.demo3+.*(..))" id="pointcut1"/>
     	<!-- 配置切面 -->
     	<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
    </aop:config>


注意:

注入accountService时,name=“accountService”,因为accountService 在 Bean生成时,已经成为了一个代理类(自动代理)

3.基于注解的实现方式(简单):

 

 <!--配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean> 
   	 
<!-- 开启注解事务 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

注意:

还需要在需要事务代理类上加上


@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT)



剩下的就交给Sping去做了!!!微笑微笑

 





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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值