spring事务管理

这几天特意去总结了一下spring事务这一块,之前只是有一个模糊的概念

百度一波,就有很多总结。我借鉴了很多前辈的总结经验

异常的一些基本知识

  • 异常的架构

  异常的继承结构:Throwable为基类,Error和Exception继承Throwable。Error和RuntimeException及其子类成为未检查异常(unchecked),其它异常成为已检查异常(checked)。

  

  • Error异常

  Error表示程序在运行期间出现了十分严重、不可恢复的错误,在这种情况下应用程序只能中止运行,例如JAVA 虚拟机出现错误。Error是一种unchecked Exception,编译器不会检查Error是否被处理,在程序中不用捕获Error类型的异常。一般情况下,在程序中也不应该抛出Error类型的异常。

  • RuntimeException异常

  Exception异常包括RuntimeException异常和其他非RuntimeException的异常。
  RuntimeException 是一种Unchecked Exception,即表示编译器不会检查程序是否对RuntimeException作了处理,在程序中不必捕获RuntimException类型的异常,也不必在方法体声明抛出 RuntimeException类。RuntimeException发生的时候,表示程序中出现了编程错误,所以应该找出错误修改程序,而不是去捕获RuntimeException。

  • Checked Exception异常

  Checked Exception异常,这也是在编程中使用最多的Exception,所有继承自Exception并且不是RuntimeException的异常都是checked Exception,上图中的IOException和ClassNotFoundException。JAVA 语言规定必须对checked Exception作处理,编译器会对此作检查,要么在方法体中声明抛出checked Exception,要么使用catch语句捕获checked Exception进行处理,不然不能通过编译。

 

1.事务有四个特性:ACID

  • 原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
  • 一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
  • 隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
  • 持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。

2 核心接口

Spring事务管理的实现有许多细节,如果对整个接口框架有个大体了解会非常有利于我们理解事务,下面通过讲解Spring的事务接口来了解Spring实现事务的具体策略。 
Spring事务管理涉及的接口的联系如下:

这里写图片描述

3.传播行为

事务的第一个方面是传播行为(propagation behavior)。当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。Spring定义了七种传播行为:

传播行为含义
PROPAGATION_REQUIRED表示当前方法必须运行在事务中。如果当前事务存在,方法将会在该事务中运行。否则,会启动一个新的事务
PROPAGATION_SUPPORTS表示当前方法不需要事务上下文,但是如果存在当前事务的话,那么该方法会在这个事务中运行
PROPAGATION_MANDATORY表示该方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常
PROPAGATION_REQUIRED_NEW表示当前方法必须运行在它自己的事务中。一个新的事务将被启动。如果存在当前事务,在该方法执行期间,当前事务会被挂起。如果使用JTATransactionManager的话,则需要访问TransactionManager
PROPAGATION_NOT_SUPPORTED表示该方法不应该运行在事务中。如果存在当前事务,在该方法运行期间,当前事务将被挂起。如果使用JTATransactionManager的话,则需要访问TransactionManager
PROPAGATION_NEVER表示当前方法不应该运行在事务上下文中。如果当前正有一个事务在运行,则会抛出异常
PROPAGATION_NESTED表示如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独地提交或回滚。如果当前事务不存在,那么其行为与PROPAGATION_REQUIRED一样。注意各厂商对这种传播行为的支持是有所差异的。可以参考资源管理器的文档来确认它们是否支持嵌套事务

 

4.使用

事务使用方式有2种,编程式和声明式(注解)

1.注解通过@Transactional 在方法上,一般使用默认的传播方式就可以,当前没有事务,就新启一个事务;当前有事务,就加入到当前事务种。

2.声明式: 

1)定义事务

2)通过commit/rollback 来实现事务执行/回滚

DefaultTransactionDefinition def = new DefaultTransactionDefinition();

def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

TransactionStatus status = txManager.getTransaction(def);

try{

     txManager.commit(status);

}catch(Exception ex){

     txManager.rollback(status);

}

5.事务传播机制

个人经验简单描述一下,采用声明式事务@Transactional

基本情景:2个类A,B,都是一个各自表插入一条数据saveA()和saveB(),在saveA()实现中调用saveB(),并在saveB()中抛出runTimeException异常

1.如果2个都不设置事务,插入语句

结果,a和b都成功插入一条数据

2.在saveA()设置事务

结果:a和b都失败

3.在saveB()设置事务

结果:a插入成功,b失败

4.在saveA(),saveB()都设置事务

结果:a和b都失败

以上都是默认传播行为

总结:

其实这些看了差不多都能明白,但是还是自己动手才会有更深的体会

最后附上我写的代码

1.2个对象

User

@Data
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String password;
    private int age;
    private String remark;

}

Friend

@Data
public class Friend implements Serializable {
    private Long id;
    private Long userId;
    private String name;
    private int age;
    private String remark;

}

没有get,set方法是使用idea 的lombox插件,自动补全

@GeneratedValue(strategy = GenerationType.IDENTITY)是实现插入能够直接返回id值

service层

@Override
@Transactional
public int saveUser(User user) {
    int flag = userDao.save(user);
    Friend friend = new Friend();
    friend.setAge(20);
    friend.setName(user.getName()+"--");
    friend.setUserId(user.getId());
    friendService.saveFriend(friend);
    return flag;
}
   @Override
    public int saveFriend(Friend friend) {
        int flag = friendDao.save(friend);
        throw new RuntimeException("test");
//        return flag;
    }

 

只要的代码就这一块,很简单。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值