• springboot事物


    一、事物的基本要素(ACID)

    1.原子性:事物开始后的所有操作要么全部做完,要么全不做,不可分割

    2.一致性:事物开始前后结束后,数据库的完整约束不被破坏

    3.隔离性:统一时间只允许一个事物请求数据,不同事物之间无干扰

    4.持久性:事物完成后,事物对数据库的所有更新将保存到数据库,不能回滚

    二、事物并发问题

    1.脏度:事物A读了事物B更新的数据,然后B回滚了,则A读到了B的脏数据

    2.不可重读度:事物A多次读取同一数据,事物B在A读的过程中对数据做了更改并提交,导致A多次读取的数据结果不一致

    3.幻度:管理员A将数据库中所有的学生的成绩都改为合格,系统管理员在A修改的过程中插入一条不及格的成绩数据,当A改结束后,发现还有一天没改,过来,就像发生幻觉一样,这种模式下,数据库性能最差

    解决不可重复读只要锁住满足的条件即可,解决欢度需要锁住整张表

    三、mysql的隔离级别(默认为repeatable-read)

    1.读未提交(read-uncommied)

    2.不可重复读(read-commied)

    3.可重复读(repeatable-read)

    4.串行化(serializable)

    四、springboot设置事物的隔离级别

    使用方式

    使用注解实现申明式事物

    在application.java上加入开启事物声明@EnableTransactionManagement,默认是开启的,可不添加

    在方法/实现类/接口上添加@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.READ_COMMITTED)

    特点

    1.如果在接口、实现类或方法上都指定了@Transactional 注解,则优先级顺序为方法>实现类>接口

    2.建议在实现方法或类注解@Transactional,而不要在接口上使用,JDK的代理机制基于接口没有问题,但CGLIB基于继承的代理,注解不能被继承,spring IOC底层两种代理都有

    3.默认只回滚RuntimeException,检查异常则不回滚,需要@Transactional(rollbackFor=Exception.class)表示任何异常都回滚

    参数解释

    propagation:事物传播行为配置,可参考org.springframework.transaction.annotation.Propagation,默认REQUIRED

     REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 

     SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。 

     MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。 

     REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。 

     NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 

     NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。 

     NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。 

    isolation:隔离级别,默认DEFAULT,选项有(DEFAULT,READ_UNCOMMITTED,READ_COMMITTED,REPEATABLE_READ,SERIALIZABLE)

    DEFAULT 使用后端数据库默认的隔离级别(Mysql默认为REPEATABLE_READ )。

    READ_UNCOMMITTED 允许读取尚未提交的更改。可能导致脏读、幻读或不可重复读。

    COMMITTED 允许从已经提交的并发事务读取。可防止脏读,但幻读和不可重复读仍可能会发生

    REPEATABLE_READ 对相同字段的多次读取的结果是一致的,除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻读仍可能发生。 

    ISOLATION_SERIALIZABLE

    四、例子 

         //如果发生Exception异常则回滚
       @Transactional(rollbackFor=Exception.class) @Override public ArticleInfo insertArtice(ArticleInfo article) { Date date = new Date(); Article tmpArticle = article.getArticle(); Content tmpContent = article.getContent(); tmpArticle.setCreateTime(date);
         //保存一条数据到数据库A tmpArticle
    = articleRep.save(tmpArticle); tmpContent.setArticleId(tmpArticle.getId()); tmpContent.setCreateTime(date);
         //保存一条数据到数据库B tmpContent
    = contentRep.save(tmpContent); article.setArticle(tmpArticle); article.setContent(tmpContent); return article; }

     

  • 相关阅读:
    C#后台解析XML字符串并获取节点值
    table动态添加tr
    时间段检索时间段
    什么是数据结构
    PERSONAL VALUES
    C#接口
    基于ArcEngine与C#的鹰眼地图实现
    ENVI/IDL与ArcGIS集成开发的三种途径
    中国地图投影(实现Lambert投影)
    Git 的下载
  • 原文地址:https://www.cnblogs.com/zincredible/p/13297716.html
Copyright © 2020-2023  润新知