事务
事务的四大特性
1.原子性:要么全部成功,要么全部失败回滚,成功就全部应用到数据库,失败则不能对数据库有任何影响
2.一致性:数据库从一个状态一致性的转为另一个状态,如A给B500,那么他们两的总额是不变的,A-500与B+500一致性
3.隔离性:多个用户并发处理数据库时,每一个用户一个事务,不被其他事务操作影响
4.持久性:数据一旦提交,数据就是永久性的
不考虑隔离将会出现的问题
1.脏读:一个事务处理过程里读取了另一个未提交的事务中的数据;
2.不可重复读:对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值;脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。(对应update)
3.幻读:事务非独立执行时发生的一种现象;幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。(对应insert)
事务的隔离级别
1.Read uncommitted(脏读)
2.Read committed(不可重复读)
3.Repeatable read(开始读取数据(事务开启)时,不再允许修改操作)
4.Serializable (序列化)(串行化顺序执行,耗性能一般不使用)
事务的传播
一般都是将事务设置在Service层 那么当我们调用Service层的一个方法的时候它能够保证我们的这个方法中执行的所有的对数据库的更新操作保持在一个事务中,在事务层里面调用的这些方法要么全部成功,要么全部失败。那么事务的传播特性也是从这里说起的。
1.ROPAGATION_REQUIRED (有就加,没有就新建)
2.PROPAGATION_SUPPORTS(有就加,没有就非事务)
3.PROPAGATION_REQUIRES_NEW(每次都会新建一个事务,并且同时将上下文中的事务挂起,执行当前新建事务完成以后,上下文事务恢复再执行。)
4.PROPAGATION_MANDATORY(要求上下文中必须要存在事务,否则就会抛出异常)
5.PROPAGATION_NOT_SUPPORTED(上下文中存在事务,则挂起事务,执行当前逻辑,结束后恢复上下文的事务。)
6.PROPAGATION_NEVER(事务更严格,上面一个事务传播级别只是不支持而已,有事务就挂起,而PROPAGATION_NEVER传播级别要求上下文中不能存在事务,一旦有事务,就抛出runtime异常,强制停止执行!这个级别上辈子跟事务有仇。)
7.PROPAGATION_NESTED (如果上下文中存在事务,则嵌套事务执行,如果不存在事务,则新建事务。)
只读事务和超时
事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务,“只读事务”仅仅是一个性能优化的推荐配置而已,并非强制你要这样做不可;
timeout事务延迟的秒数,超时自动回滚,默认是none,没有超时
myBatis为例 基于注解的声明式事务管理配置,xml配置
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation"> <value>classpath:mybatis-config.xml</value> </property> </bean> <!-- mybatis mappers, scanned automatically --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage"> <value> com.baobao.persistence.test </value> </property> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> <!-- 配置spring的PlatformTransactionManager,名字为默认值 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 开启事务控制的注解支持 --> <tx:annotation-driven transaction-manager="transactionManager"/></span></span>
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
<!-- 事物切面配置 --> <tx:advice id="advice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="update*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/> <tx:method name="insert" propagation="REQUIRED" read-only="false"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="testService" expression="execution (* com.baobao.service.MyBatisService.*(..))"/> <aop:advisor advice-ref="advice" pointcut-ref="testService"/> </aop:config>
hibernate
为例 基于注解的声明式事务管理配置,xml配置
全注解 <?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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <context:annotation-config /> <context:component-scan base-package="com.bluesky" /> <tx:annotation-driven transaction-manager="transactionManager"/> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml" /> <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /> </bean> <!-- 定义事务管理器(声明式的事务) --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> </beans>
使用tx标签配置的拦截器 <?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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <context:annotation-config /> <context:component-scan base-package="com.bluesky" /> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml" /> <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /> </bean> <!-- 定义事务管理器(声明式的事务) --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" propagation="REQUIRED" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="interceptorPointCuts" expression="execution(* com.bluesky.spring.dao.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" /> </aop:config> </beans>