zoukankan      html  css  js  c++  java
  • spring_05事务管理

    spring事物管理

    什么是事物

    事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败。

    事务特性

    原子性:强调事务的不可分割.
    一致性:事务的执行的前后数据的完整性保持一致.
    隔离性:一个事务执行的过程中,不应该受到其他事务的干扰
    持久性:事务一旦结束,数据就持久到数据库

    如果不考虑隔离性引发安全性问题

    脏读:一个事务读到了另一个事务的未提交的数据
    不可重复读:一个事务读到了另一个事务已经提交的update的数据导致多次查询结果不一致.
    幻读:一个事务读到了另一个事务已经提交的insert的数据导致多次查询结果不一致.

    解决读问题:设置事务隔离级别

    未提交读:脏读,不可重复读,虚读都有可能发生
    已提交读:避免脏读。但是不可重复读和虚读有可能发生
    可重复读:避免脏读和不可重复读.但是虚读有可能发生.
    串行化的:避免以上所有读问题.

    Mysql默认:可重复读
    Oracle默认:读已提交

    事物操作

    打开事物 | 提交事物 | 回滚事务
    

    spring封装了事物管理代码

    因为在不同平台,操作事物的代码各不相同,spring提供了一个接口

    PlatformTransactionManager 接口

    JDBCTransactionManager 针对JDBC的实现类

    HibernateTransactionManager 针对Hibernate的实现类

    Spring事务管理的三个接口:

    1.PlatformTransactionManager 事物管理器
    2.TransactionDefinition 事务定义信息(隔离、传播、超时、只读)
    3.TransactionStatus 事务具体运行状态

    事物的传播行为

    事务的传播行为:主要是解决业务层方法之间的相互调用的问题

    事务的传播行为有七种,又分为三类:

    第一类共同点:如果 A 方法中有事务,则调用 B 方法时就用该事务,即:A和B方法在同一个事务中。

    PROPAGATION_REQUIRED:如果 A 方法中没有事务,则调用 B 方法时就创建一个新的事务,即:A和B方法在同一个事务中。
    PROPAGATION_SUPPORTS:如果 A 方法中没有事务,则调用 B 方法时就不使用该事务。
    PROPAGATION_MANDATORY:如果 A 方法中没有事务,则调用 B 方法时就抛出异常。

    第二类共同点:A方法和B方法没有在同一个事务里面。

    PROPAGATION_REQUIRES_NEW:如果 A 方法中有事务,则挂起并新建一个事务给 B 方法。
    PROPAGATION_NOT_SUPPORTED:如果 A 方法中有事务,则挂起。
    PROPAGATION_NEVER:如果 A 方法中有事务,则报异常。

    第三类:如果 A 方法有的事务执行完,设置一个保存点,如果 B 方法中事务执行失败,可以滚回保存点或初始状态。

    PROPAGATION_NESTED :如果当前事务存在,则嵌套事务执行。

    spring支持两种方式事务管理

    -编程式的事务管理
    .在实际应用中很少使用
    .通过TransactionTemplate手动管理事务

    .具体:
    	在业务层中使用TransactionTemplate
    	TransactionTemplate依赖DataSourceTransactionManager
    	DataSourceTransactionManager依赖DataSource构造
    .例:
    
    	<!-- 指定spring读取db.properties文件的配置信息 -->
    	<context:property-placeholder location="db.properties"/>
    	<!-- 将连接池放入spring容器 -->
    	<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    		<property name="driverClass" value="${jdbc.driverClass}"></property>
    		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
    		<property name="user" value="${jdbc.user}"></property>
    		<property name="password" value="${jdbc.password}"></property>
    	</bean>
    	<!-- 配置DAO -->
    	<bean name="accountDao" class="org.spring.work.AccountDaoImpl">
    		<property name="dataSource" ref="dataSource"></property>
    	</bean>
    	<!-- 配置业务层 -->
    	<bean name="accountService" class="org.spring.work.AccountServiceImpl">
    		<property name="accountDao" ref="accountDao"></property>
    		<!-- 注入事务管理模板 -->
    		<property name="transactionTemplate" ref="transactionTemplate"></property>
    	</bean>
    	<!-- 配置事务管理的模板 -->
    	<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    		<property name="transactionManager" ref="transactionManager"></property>
    	</bean>
    	<!-- 配置事务管理器 -->
    	<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    		<property name="dataSource" ref="dataSource"></property>
    	</bean>
    

    -使用xml配置声明事务
    .开发中推荐使用(代码侵入性最小)
    .spring的声明式事务是通过AOP实现的

    .方式一:基于TransactionProxyFactoryBean使用XML配置声明式事务(原始方式)
    
    	<!-- 配置事务管理器 -->
    	<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    		<property name="dataSource" ref="dataSource"></property>
    	</bean>
    	<!-- 配置业务层代理 -->
    	<bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<!-- 配置目标对象 -->
    		<property name="target" ref="accountService"></property>
    		<!-- 注入事务管理器 -->
    		<property name="transactionManager" ref="transactionManager"></property>
    		<!-- 注入事务属性 -->
    		<property name="transactionAttributes">
    			<props>
    				<!-- 
    					prop的格式:
    						*PROPAGATION	:事务的传播行为
    						*ISOLATION		:事务的隔离级别
    						*readOnly		:只读
    						*-Exception		:发生哪些异常回滚事务
    						*+Exception 	:发生哪些异常事务不回滚				
    				 -->
    				<prop key="transfer">PROPAGATION_REQUIRED</prop>
    			</props>
    		</property>
    	</bean>
    
    
    
    
    .方式二:基于AspectJ使用XML配置声明事务 tx/aop
    
    	<!-- 配置事务管理器 -->
    	<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    		<property name="dataSource" ref="dataSource"></property>
    	</bean>
    
    	<!-- 配置事务的通知:(事务的增强) -->
    	<tx:advice id="txAdvice" transaction-manager="transactionManager">
    		<tx:attributes>
    			<!-- 
    				propagation	:事务传播行为
    				isolation	:事务隔离级别
    				read-only	:只读
    				rollback-for:发生哪些异常回滚
    				no-rollback-for:发生那些异常不回滚
    				timeout		:过期信息
    			 -->
    			<tx:method name="transfer" propagation="REQUIRED"/>
    		</tx:attributes>
    	</tx:advice>
    
    	<!-- 配置切面 -->
    	<aop:config>
    		<!-- 配置切入点 -->
    		<aop:pointcut expression="execution(* org.spring.work3.AccountService+.*(..))" id="pointcut1"/>
    		<!-- 配置切面 -->
    		<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
    	</aop:config>
    
    .方式三:基于注解的方式
    
    
    	<!-- 配置事务管理器 -->
    	<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    		<property name="dataSource" ref="dataSource"></property>
    	</bean>
    	<!-- 开启注解事务 -->
    	<tx:annotation-driven transaction-manager="transactionManager"/>
    
    
    	/**
    	 * 转账事务实现类
    	 * @Transactional注解中的属性:19:32 2018/1/24
    	 * propagation	:事务的传播行为
    	 * isolation	:事务的隔离级别
    	 * readOnly		:只读
    	 * rollbackFor	:发生那些异常回滚
    	 * noRollbackFor:发生那些异常不回滚
    	 */
    	@Transactional
    	public class AccountServiceImpl implements AccountService { ...}
  • 相关阅读:
    登录、注册、忘记密码 流程图
    用心每一天,不忘初心,方能走远
    HttpContext.Current.Request.ServerVariables
    Bootstrap实现弹出框和提示框效果代码
    jquery.each()
    js获取页面url
    jquery获取ul中的第一个li
    sql server 取文件名函数 转载
    jquery手风琴
    给母亲的信
  • 原文地址:https://www.cnblogs.com/nm666/p/8343227.html
Copyright © 2011-2022 走看看