spring事务管理

Spring事务管理

首先澄清一个误点:Spring本身是没有事务一说的,数据库对事务的支持才是Spring事务的本质。
Spring事务分为两类:

  1. 声明式事务:
    手动编写代码进行事务管理(很少使用)
  2. 编程式事务
    • 基于TransactionProxyFactoryBean的方式(很少使用)
      需要为每个进行事务管理的类,配置一TransactionProxyFactoryBean进行增强

    • 基于AspectJ的xml方式(经常使用)
      一旦配置好,类上不需要添加任何东西

    • 基于注解(经常使用)
      配置简单,需要在业务层类上添加一个@Transactional的注解

事务特性及行为

事物是指一组逻辑上的操作,要么全部成功,不然全部失败。

特性

原子性( Atomicity )

事务中所有操作是不可再分割的原子单元。事务中所有操作要么都执行成功,要么都执行失败。

一致性( Consistency )

事务执行后,数据库状态与其他业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账户余额之和应该保持不变。

隔离性( Isolation )

隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会互相干扰。

持久性( Durability )

一旦事务提交成功,事务中所有的数据操作都必须被持久化保存到数据库中,即使提交事务后,数据库崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。

传播行为

事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。
例如:methodA事务方法调用methodB事务方法时,methodB是继续在调用者methodA的事务中运行呢,还是为自己开启一个新事务运行,这就是由methodB的事务传播行为决定的。

Spring定义了七种传播行为:

1.PROPAGATION_REQUIRED

@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
 methodB();
// do something
}
@Transactional(propagation = Propagation.REQUIRED)
public void methodB() {
    // do something

单独调用methodB方法时,因为当前上下文不存在事务,所以会开启一个新的事务。
调用methodA方法时,因为当前上下文不存在事务,所以会开启一个新的事务。当执行到methodB时,methodB发现当前上下文有事务,因此就加入到当前事务中来。

2.PROPAGATION_SUPPORTS

如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。

@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
 methodB();
// do something
}
// 事务属性为SUPPORTS
@Transactional(propagation = Propagation.SUPPORTS)
public void methodB() {
    // do something
}

单纯的调用methodB时,methodB方法是非事务的执行的。当调用methdA时,methodB则加入了methodA的事务中,事务地执行。

3.PROPAGATION_MANDATORY

如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常

@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
 methodB();
// do something
}
 
// 事务属性为MANDATORY
@Transactional(propagation = Propagation.MANDATORY)
public void methodB() {
    // do something
}

当单独调用methodB时,因为当前没有一个活动的事务,则会抛出异常throw new IllegalTransactionStateException(“Transaction propagation ‘mandatory’ but no existing transaction found”);当调用methodA时,methodB则加入到methodA的事务中,事务地执行。

4.PROPAGATION_REQUIRES_NEW

使用PROPAGATION_REQUIRES_NEW,需要使用 JtaTransactionManager作为事务管理器。
它会开启一个新的事务。如果一个事务已经存在,则先将这个存在的事务挂起。

5.PROPAGATION_NOT_SUPPORTED

PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务。使用PROPAGATION_NOT_SUPPORTED,也需要使用JtaTransactionManager作为事务管理器。

6.PROPAGATION_NEVER

总是非事务地执行,如果存在一个活动事务,则抛出异常。

7.PROPAGATION_NESTED

如果一个活动的事务存在,则运行在一个嵌套的事务中。 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。


@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
 methodB();
// do something
}
 
// 事务属性为MANDATORY
@Transactional(propagation = Propagation.MANDATORY)
public void methodB() {
    // do something
}

spring事务传播详细解读:原文

隔离级别

基于元数据的 Spring 声明性事务 :

  • Isolation 属性一共支持五种事务设置,具体介绍如下:
  • DEFAULT 使用数据库设置的隔离级别 ( 默认 ) ,由 DBA 默认的设置来决定隔离级别
  • READ_UNCOMMITTED 会出现脏读、不可重复读、幻读 ( 隔离级别最低,并发性能高 )
  • READ_COMMITTED 会出现不可重复读、幻读问题(锁定正在读取的行)
  • REPEATABLE_READ 会出幻读(锁定所读取的所有行)
  • SERIALIZABLE 保证所有的情况不会发生(锁表)
名称备注脏读不可重复读幻读
DEFAULT使用数据库设置的隔离级别 ( 默认 )
READ_UNCOMMITTED隔离级别最低,并发性能高
READ_COMMITTED锁定正在读取的行-
REPEATABLE_READ锁定所读取的所有行--
SERIALIZABLE保证所有的情况不会发生(锁表)---

spring事务传播及隔离可参照

参照:spring事务管理

使用

采用纯注解方式-简便

  1. 启动类@EnableTransactionManagement开启事务
  2. 业务类、方法上均可以添加注解:
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
    指定是否开启事务
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值