mysql事务(单体)

一、mysql本地事务

  1. 所谓本地事务,是指该事务仅在当前工程内有效。

  2. 事务的概念:事务是逻辑上一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败。

  3. 事务的四个特性(ACID):
    1). 原子性(atomicity):“原子”的本意是“不可再分”,事务的原子性表现为一个事务中涉及到的多个操作在逻辑上缺一不可。事务的原子性要求事务中的所有操作要么都执行,要么都不执行。

    2). 一致性(consistency):“一致”指的是数据的一致,具体是指:所有数据都处于满足业务规则的一致性状态。一致性原则要求:一个事务中不管涉及到多少个操作,都必须保证事务执行之前数据是正确的,事务执行之后数据仍然是正确的。如果一个事务在执行的过程中,其中某一个或某几个操作失败了,则必须将其他所有操作撤销,将数据恢复到事务执行之前的状态,这就是回滚。

    3). 隔离性(isolation):在应用程序实际运行过程中,事务往往是并发执行的,所以很有可能有许多事务同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。隔离性原则要求多个事务在并发执行过程中不会互相干扰

    4). 持久性(durability):持久性原则要求事务执行完成后,对数据的修改永久的保存下来,不会因各种系统错误或其他意外情况而受到影响。通常情况下,事务对数据的修改应该被写入到持久化存储器中。

  4. 事务的隔离级别
    事务并发引起一些读的问题:
    1). 脏读 一个事务可以读取另一个事务未提交的数据

    2).不可重复读 一个事务可以读取另一个事务已提交的数据 单条记录前后不匹配

    3).虚读(幻读) 一个事务可以读取另一个事务已提交的数据 读取的数据前后多了点或者少了点

    并发写:使用mysql默认的锁机制(独占锁)

    解决读问题:设置事务隔离级别

    read uncommitted(0)

    read committed(2)

    repeatable read(4)

    Serializable(8)

    隔离级别越高,性能越低。

    一般情况下:脏读是不可允许的,不可重复读和幻读是可以被适当允许的。
    在这里插入图片描述
    相关提示:目前的mysql解决了可重复读隔离级别的幻读问题

  5. 相关命令
    查看全局事务隔离级别:SELECT @@global.tx_isolation

    设置全局事务隔离级别:set global transaction isolation level read committed;

    查看当前会话事务隔离级别:SELECT @@tx_isolation

    设置当前会话事务隔离级别:set session transaction isolation level read committed;

    查看mysql默认自动提交状态:select @@autocommit

    设置mysql默认自动提交状态:set autocommit = 0;【不自动提交】

    开启一个事务:start transaction;

    提交事务:commit

    回滚事务: rollback

    在事务中创建一个保存点:savepoint tx1

    回滚到保存点:rollback to tx1

    注意:“如果mysql 8+”,则把tx_isolation替换为transaction_isolation

  6. 传播行为
    事务的传播行为不是jdbc规范中的定义。传播行为主要针对实际开发中的问题
    在这里插入图片描述
    七种传播行为:

    REQUIRED 支持当前事务,如果不存在,就新建一个

    SUPPORTS 支持当前事务,如果不存在,就不使用事务

    MANDATORY 支持当前事务,如果不存在,抛出异常

    REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务

    NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务

    NEVER 以非事务方式运行,如果有事务存在,抛出异常

    NESTED 如果当前事务存在,则嵌套事务执行(嵌套式事务)

    依赖于JDBC3.0提供的SavePoint技术

    删除用户 删除订单。在删除订单后,设置savePoint,执行删除用户。删除订单和删除用户在同一事务中,删除用户失败,事务回滚savePoint,由用户控制视图提交还是回滚

    这七种事务传播机制最常用的就两种:

    REQUIRED:一个事务,要么成功,要么失败

    REQUIRES_NEW:两个不同事务,彼此之间没有关系。一个事务失败了不影响另一个事务
    传播行为伪代码模拟:有a,b,c,d,e等5个方法,a中调用b,c,d,e方法的传播行为在小括号中标出

    a(required){
    b(required);
    c(requires_new);
    d(required);
    e(requires_new);
    // a方法的业务
    }

    问题:

    1). a方法的业务出现异常,会怎样?a,b,d回滚 c,e不回滚
    2). d方法出现异常,会怎样?a,b,d回滚 c,e不回滚
    3). e方法出现异常,会怎样?a,b,d,e回滚 c不回滚,e方法出异常会上抛影响到上级方法
    4). b方法出现异常,会怎样?a,b回滚 c,d,e未执行

    加点难度:
    a(required){
    b(required){
    f(requires_new);
    g(required)
    }
    c(requires_new){
    h(requires_new)
    i(required)
    }
    d(required);
    e(requires_new);
    // a方法的业务
    }

    问题:

    1). a方法业务出异常 a,b,g,d回滚 c,h,i,e,f不回滚
    2). b方法出异常 b,a,g回滚 f不回滚 b方法下面的都不执行
    3). c方法出异常c,i,a,b,g,回滚 f不回滚 d,e不执行
    4). d方法出异常 d,a,b,g回滚 f,c,h,i不回滚 e不执行
    5). e方法出异常 e,a,b,g,d回滚 c,h,i,f不回滚
    6). f方法出异常 f,b,a回滚 f下面的都不执行
    7). g方法出异常 g,b,a回滚 f不回滚 g下面的都不执行
    8). h方法出异常 h,c,a,b,g回滚 f不回滚 i,d,e不执行
    9). i方法出异常 i,c,a,b,g回滚 f,h不回滚 d,e不执行

  7. 回滚策略
    事务很重要的另一个特征是程序出异常时,会回滚。但并不是所有的异常都会回滚。
    默认情况下的回滚策略:
    1).运行时异常:不受检异常,没有强制要求try-catch,都会回滚。例如:ArrayOutOfIndex,OutofMemory,NullPointException
    2).编译时异常:受检异常,必须处理,要么try-catch要么throws,都不回滚。例如:FileNotFoundException

    可以通过@Transactional注解的下面几个属性改变回滚策略:
    在这里插入图片描述
    rollbackFor:指定的异常必须回滚

    noRollbackFor:发生指定的异常不用回滚

  8. 超时事务
    @Transactional注解,还有一个属性是timeout超时时间,单位是秒。
    在这里插入图片描述
    timeout=3:是指第一个sql开始执行到最后一个sql结束执行之间的间隔时间。

    即:超时时间(timeout)是指数据库超时,不是业务超时。

  9. 只读事务
    @Transactional注解最后一个属性是只读事务属性
    在这里插入图片描述
    如果一个方法标记为readOnly=true事务,则代表该方法只能查询,不能增删改。readOnly默认为false

二、分布式事务

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值