spring事务的几种传播特性:
PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED:支持当前事务如果当前事务存在,则执行一个嵌套事务如果当前没有事务就新建一个事务。
spring事务的隔离级别:
ISOLATION_DEFAULT:
这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应
ISOLATION_READ_UNCOMMITTED:
这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
ISOLATION_READ_COMMITTED:
保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
ISOLATION_REPEATABLE_READ:
这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
ISOLATION_SERIALIZABLE:
这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。
spring3.x集成Mybatis3.x配置声明式事务:
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-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
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/jee
http://www.springframework.org/schema/jee/spring-jee-3.2.xsd">
<!--读取外部的属性文件配置参数 -->
<context:property-placeholder location="classpath:conf.properties" />
<!--自动扫描组件-->
<context:component-scan base-package="com.tliu.case2" />
<bean id="BasicDataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<!-- 数据库基本信息配置 -->
<property name="url" value="${oracle.url}"/>
<property name="driverClassName" value="${oracle.driver}"/>
<property name="username" value="${oracle.username}"/>
<property name="password" value="${oracle.password}"/>
<property name="maxIdle" value="${dbcp2.maxIdle}"/>
<property name="minIdle" value="${dbcp2.minIdle}"/>
<property name="initialSize" value="${dbcp2.initialSize}"/>
<property name="timeBetweenEvictionRunsMillis" value="${dbcp2.timeBetweenEvictionRunsMillis}"/>
<property name="poolPreparedStatements" value="${dbcp2.poolPreparedStatements}"/>
<property name="maxOpenPreparedStatements" value="${dbcp2.maxOpenPreparedStatements}"/>
<property name="removeAbandonedOnBorrow" value="${dbcp2.removeAbandonedOnBorrow}"/>
<property name="removeAbandonedTimeout" value="${dbcp2.removeAbandonedTimeout}"/>
<property name="testOnBorrow" value="${dbcp2.testOnBorrow}"/>
<property name="testOnReturn" value="${dbcp2.testOnReturn}"/>
<property name="testWhileIdle" value="${dbcp2.testWhileIdle}"/>
<property name="validationQuery" value="${dbcp2.validationQuery}"/>
</bean>
<!-- 会话工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="BasicDataSource" />
<property name="mapperLocations" value="classpath:com/tliu/case2/domain/*Mapper.xml" />
<property name="typeAliasesPackage" value="com.tliu.case2.domain" />
</bean>
<!-- Mapper接口类自动装配 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.tliu.case2.mapper" />
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="BasicDataSource" />
</bean>
<!-- 声明式事务插入、修改、删除操作使用事务,查询方法不需要事务 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" rollback-for="RuntimeException" />
<tx:method name="remove*" propagation="REQUIRED" rollback-for="RuntimeException" />
<tx:method name="update*" propagation="REQUIRED" rollback-for="RuntimeException" />
<tx:method name="init*" propagation="REQUIRED" rollback-for="RuntimeException" />
<tx:method name="find*" propagation="SUPPORTS" />
<tx:method name="get*" propagation="SUPPORTS" />
<tx:method name="*" propagation="REQUIRED" rollback-for="RuntimeException" />
</tx:attributes>
</tx:advice>
<!-- 事务通知 -->
<aop:config>
<aop:pointcut expression="execution(* com.tliu.case2.service..*.*(..))"
id="servicePC" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="servicePC" />
</aop:config>
</beans>
关于脏读,不可重复读,幻觉读的名词说明:
脏读:
指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,
另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据, 那么
另外一 个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。
不可重复读:
指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同
一数据。 那么,在第一个事务中的两次读数据之间,由于第二个事务的修 改,那么第一
个事务两次读到的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不
一样的,因此称为是不可重复读。
幻觉读:
指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,
这种修改涉及 到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改
是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有
修改的数据行,就好象发生了幻觉一样。