Spring事务


Spring事务的本质是,封装数据库事务,而数据库事务的本质则是基于数据库锁实现指定隔离级别的事务。

事务的基本特性

  • 原子性(Atomicity): 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;

  • 一致性(Aonsistency): 执行事务前后,数据保持一致;

  • 隔离性(Isolation): 并发访问数据库时,一个用户的事物不被其他事务所干扰也就是说多个事务并发执行时,一个事务的执行不应影响其他事务的执行;

  • 持久性(Durability): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

Spring事务管理方式

编程式事务管理

需要按照规则编写代码,侵入性高。

TransactionTemplate、PlatformTransactionManager

@Autowired
private TransactionTemplate transactionTemplate;
public void testTransaction() {
  transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    @Override
    protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
      try {
        // ...  业务代码
      } catch (Exception e){
        //回滚
        transactionStatus.setRollbackOnly();
      }
    }
  });
}
----------------
@Autowired
private PlatformTransactionManager transactionManager;
public void testTransaction() {
  TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
    try {
      // ...  业务代码
      transactionManager.commit(status);
    } catch (Exception e) {
      transactionManager.rollback(status);
    }
}

声明式事务管理

基于注解的实现

基于AOP实现,代码侵入性小。

作用范围

方法 :推荐将注解使用于方法上,不过需要注意的是:该注解只能应用到 public 方法上,否则不生效。

类 :如果这个注解使用在类上的话,表明该注解对该类中所有的 public 方法都生效。

接口 :不推荐在接口上使用。

@Transactional(propagation=propagation.PROPAGATION_REQUIRED)
public void daoMethod {
// ... 业务代码
}

基于XML的实现

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
	
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<tx:method name="get*" propagation="NOT_SUPPORTED" />
			<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>
		  <tx:method name="del*" propagation="REQUIRED" rollback-for="Exception" />
		  <!-- ... -->
		</tx:attributes>
	</tx:advice>
	
	<!--  配置参与事务的类 -->
	<aop:config>
		<aop:pointcut id="transcationPointcut" expression="execution(* service.impl.*.*(..))"/>
		<aop:advisor pointcut-ref="transcationPointcut" advice-ref="txAdvice" />
	</aop:config>

事务注解

注解说明

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {

	@AliasFor("transactionManager")
	String value() default "";

	@AliasFor("value")
	String transactionManager() default "";

	Propagation propagation() default Propagation.REQUIRED;

	Isolation isolation() default Isolation.DEFAULT;

	int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

	boolean readOnly() default false;

	Class<? extends Throwable>[] rollbackFor() default {};

	String[] rollbackForClassName() default {};

	Class<? extends Throwable>[] noRollbackFor() default {};

	String[] noRollbackForClassName() default {};
}

事务传播机制

事务类型说明
PROPAGATION_REQUIRED表示如果当前事务存在,则支持当前事务。否则,会启动一个新的事务。xorm中默认事务类型。
PROPAGATION_REQUIRES_NEW表示新建一个全新Session开启一个全新事务,如果当前存在事务,则把当前事务挂起。
PROPAGATION_NESTED表示如果当前事务存在,则在嵌套事务内执行,如嵌套事务回滚,则只会在嵌套事务内回滚,不会影响当前事务。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
PROPAGATION_SUPPORTS表示如果当前事务存在,则支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_NOT_SUPPORTED表示以非事务方式执行操作,如果当前存在事务,则新建一个Session以非事务方式执行操作,把当前事务挂起。
PROPAGATION_MANDATORY表示如果当前事务存在,则支持当前事务,如果当前没有事务,则返回事务嵌套错误。
PROPAGATION_NEVER表示以非事务方式执行操作,如果当前存在事务,则返回事务嵌套错误。
PROPAGATION_NOT_REQUIRED表示如果当前没有事务,就新建一个事务,否则返回错误。

事务失效场景

  1. @Transactional 注解只有作用到 public 方法上事务才生效,不推荐在接口上使用。

  2. 避免同一个类中自调用 @Transactional 注解的方法。

  3. 正确的设置 @Transactional 的 rollbackFor 和 propagation 属性。

  4. 组件类上需配置Spring的注解,否则Spring无法识别为Bean。

  5. 事务内部异常被捕获,事务内部抛出的异常范围大于注解配置异常。

  6. 数据源未配置事务管理器。

事务代理

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值