spring事务--Propagation

Spring提供了声明式事务,为了对事务的精细控制,spring提供了事务的传播属性。

PROPAGATION_REQUIRED

这是默认的传播属性值,如果当前已经存在事务,那么加入该事务,如果不存在事务,创建一个事务。

@Transactional
public void service(){
    serviceA();
    serviceB();
}

@Transactional
serviceA();
@Transactional
serviceB();

serviceA和serviceB都声明了事务,默认情况下,propagation=PROPAGATION_REQUIRED,整个service调用过程中,只存在一个共享的事务,当有任何异常发生的时候,所有操作回滚。

PROPAGATIOIN_SUPPORTS

如果当前已经存在事务,那么加入该事务,否则创建一个所谓的空事务(可以认为无事务执行)。

public void service(){
     serviceA();
     throw new RunTimeException();
}

@Transactional(propagation=Propagation.SUPPORTS)
serviceA();

serviceA执行时当前没有事务,所以service中抛出的异常不会导致serviceA回滚。

PROPAGATION_MANDATORY

当前必须存在一个事务,否则抛出异常。

public void service(){
     serviceB();
     serviceA();
}
serviceB(){
    do sql
}
@Transactional(propagation=Propagation.MANDATORY)
serviceA(){
    do sql 
}

这种情况执行service会抛出异常,如果defaultAutoCommit=true,则serviceB是不会回滚的,defaultAutoCommit=false,则serviceB执行无效。

PROPAGATION_REQUIRES_NEW

暂停当前事务(当前无事务则不需要),创建一个新事务。两个事务没有依赖关系,可以实现新事务回滚,但外部事务继续执行。

@Transactional
public void service(){
    serviceB();
    try{
        serviceA();
    }catch(Exception e){
    }
}
serviceB(){
    do sql
}
@Transactional(propagation=Propagation.REQUIRES_NEW)
serviceA(){
    do sql 1
    1/0; 
    do sql 2
}

当调用service接口时,由于serviceA使用的是REQUIRES_NEW,它会创建一个新的事务,但由于serviceA抛出了运行时异常,所以serviceB是正常提交的。

Propagation.NOT_SUPPORTED

如果当前存在事务,挂起当前事务,然后新的方法在没有事务的环境中执行,没有spring事务的环境下,sql的提交完全依赖于defaultAutoCommit属性值 。

@Transactional
public void service(){
     serviceB();
     serviceA();
}
serviceB(){
    do sql
}
@Transactional(propagation=Propagation.NOT_SUPPORTED)
serviceA(){
    do sql 1
    1/0;
    do sql 2
}

PROPAGATION_NEVER

如果当前存在事务,则抛出异常,否则在无事务的环境上执行代码。

public void service(){
    serviceB();
    serviceA();
}
serviceB(){
    do sql
}
@Transactional(propagation=Propagation.NEVER)
serviceA(){
    do sql 1
    1/0;
    do sql 2
}

PROPAGATION_NESTED

如果当前存在事务,则使用SavePoint技术把当前事务状态进行保存,然后底层共用一个连接,当NESTED内部出错的时候,自动回滚到SavePoint这个状态,只要外部捕获到异常,就可以继续进行外部的事务提交,而不受到内嵌业务的干扰,但是,如果外部事物抛出异常,整个大事务都会回滚。

@Transactional
public void service(){
    serviceA();
    try{
        serviceB();
    }catch(Exception e){
    }
}
serviceA(){
    do sql
}
@Transactional(propagation=Propagation.NESTED)
serviceB(){
    do sql1
    1/0;
    do sql2
}

serviceB是一个内嵌的业务,内部抛出的运行时异常,所以serviceB整个被回滚,由于service捕获异常,所以serviceA是可以正常提交的。

 

最后欢迎大家访问我的个人网站:1024s​​​​​​​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值