基于 @Transactional 的声明式事务管理
在spring-mybatis.xml文件中配置
<!-- 定义事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据库连接池-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- <!– 使用注解定义事务,需要添加Transactional注解属性 –>-->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
使用:一般是用在service层,直接在类或方法上使用
@Transactional(isolation = Isolation.DEFAULT,rollbackFor = Exception.class, propagation = Propagation.REQUIRED, readOnly = false, timeout = -1)
@Override
public int insertRole(Role role) {
int i = roleMapper.insertTrim(role);
return i;
}
事务的五大特性:
Spring事务的隔离级别
一般使用默认属性: Default 由使用的数据库来决定事务的隔离级别.
-
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
读取未提交数据(会出现脏读, 不可重复读) 基本不使用
-
@Transactional(isolation = Isolation.READ_COMMITTED)
读取已提交数据(会出现不可重复读和幻读)
-
@Transactional(isolation = Isolation.REPEATABLE_READ)
可重复读(会出现幻读)
-
@Transactional(isolation = Isolation.SERIALIZABLE)
串行化
-
@Transactional(isolation = Isolation.DEFAULT)
默认级别,MYSQL: 默认为REPEATABLE_READ级别 SQLSERVER: 默认为READ_COMMITTED
-
总结
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
大多数的数据库默认隔离级别为 Read Commited,比如 SqlServer、Oracle
少数数据库默认隔离级别为:Repeatable Read 比如: MySQL InnoDB
spring事务的传播行为
如果是查询一般使用:propagation=Propagation.SUPPORTS 如果没有外部事务值不开启事务,如果存在外部事务,则融入该事务,使用外部事务的规则.主要因为查询不太依赖事务.
如果是增删改一般使用:propagation=Propagation.REQUIRED 如果存在外部事务则使用外部事务,如果不存在则自己新建一个事务,适用于增删改,该传播属性也是默认值
-
**@Transactional(propagation=Propagation.REQUIRED) **
如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
-
@Transactional(propagation=Propagation.NOT_SUPPORTED)
容器不为这个方法开启事务
-
@Transactional(propagation=Propagation.REQUIRES_NEW)
不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行旧的事务
-
@Transactional(propagation=Propagation.MANDATORY)
必须在一个已有的事务中执行,否则抛出异常
-
@Transactional(propagation=Propagation.NEVER)
必须在一个没有的事务执行,否则抛出异常(与Propagation.MANDATORY相反)
-
@Transactional(propagation=Propagation.SUPPORTS)
如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他 bean没有声明事务,那就不用事务.
spring事务超时时间
一般使用 -1 默认值,由数据库自己决定超时时间
@Transactional(timeout=30) **默认是-1,不超时
spring事务读写性
ReadOnly = true | false
trur:只读,适用于查询
false:可读写 使用于增删改
spring事务的回滚规则
一般使用直接一个大异常,不管是什么异常都要进行回滚Exception
-
@Transactional(rollbackFor=RuntimeException.class)
用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则事务回滚。
-
@Transactional(rollbackForClassName=“RuntimeException”)
用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚
-
@Transactional(noRollbackFor=RuntimeException.class)
用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚
-
@Transactional(noRollbackForClassName=RuntimeException.class)
用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚
第二种 基于Aspect AOP配置事务
也是在spring-mybatis.xml文件中配置
<!-- 定义事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据库连接池-->
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- 配置事务通知 transaction-manager= 这个的值是事务管理器的id-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- attributes= 事务属性-->
<tx:attributes>
<!-- 在所有以create开头的的方法上使用事务i solation = 隔离级别 propagation= 传播行为 rollback-for = 回滚规则 -->
<tx:method name="create*" propagation="REQUIRED" timeout="300" rollback-for="java.lang.Exception" isolation="DEFAULT"/>
<!-- 在所有以delete开头的的方法上使用事务 -->
<tx:method name="delete*" propagation="REQUIRED" timeout="300" rollback-for="java.lang.Exception" />
<!-- 在所有以更新开头的的方法上使用事务 -->
<tx:method name="update*" propagation="REQUIRED" timeout="300" rollback-for="java.lang.Exception"/>
<!-- 在所有以find开头的的方法上使用只读事务 -->
<tx:method name="find*" propagation="REQUIRED" read-only="true" timeout="300"/>
<!-- 其它任意的方法上使用只读事务 -->
<tx:method name="*" propagation="REQUIRED" read-only="false" timeout="300" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
</tx:attributes>
</tx:advice>
<aop:config>
<!-- 其中第一个*代表返回值,第二*代表service下子包,第三个*代表方法名,“(..)”代表方法参数-->
<!-- 切入点配置 方法修饰符 + 方法返回值 + 方法所在类路径 + 方法名(参数)-->
<aop:pointcut id="txPointcut" expression="execution(public * com.spring.order.service..*.*(..))"/>
<!-- <!– 通知 –>-->
<!-- <aop:advisor pointcut-ref="txPointcut" advice-ref="txAdvice"/>-->
</aop:config>