MySQL事务和spring事务

MySQL事务和spring事务

我一直想到事务就是spring里面学到的事务,但是实际上

Spring事务本质是对数据库事务的支持,如果数据库不支持事务(例如MySQL的MyISAM引擎不支持事务),则Spring事务也不会生效。

所以还是要从Mysql的事务学起。

MySQL事务

  1. 事务是什么

    • 是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合
  2. 事务的四大特性

    • 原子性
      事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做
    • 一致性
      事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
    • 隔离性
      一个事务的执行不能被其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
    • 持续性
      也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响
  3. 脏读,不可重复读,幻读

脏读:比如事务A执行的过程中,读到了事务B未提交的内容。(脏数据就是别的事务修改表里的数据但是还没有最后提交commit前的)

不可重复度:指一个事务在前后两次查询的结果不一致。(更注重别的事务的更新数据)

幻读:幻读是指前后两次相同条件下的查询,后一次查询读到了前一次查询没有的行数据。(更注重别的事务的插入数据)

  • 脏读:一个事务对数据进行了增删改查,但是未提交事务。另一个事物可以读取到未提交的数据,如果第一个事务进行了回滚,那么第二个事务就读到了脏数据。

    例子:

    领导给张三发工资,10000元已打到张三账户,但该事务还未提交,正好这时候张三去查询工资,发现10000元已到账。这时领导发现张三工资算多了5000元,于是回滚了事务,修改了金额后将事务提交。最后张三实际到账的只有5000元。

  • 不可重复读:一次事务发生了两次读操作,两个读操作之间发生了另一个事务对数据修改操作,这时候第一次和第二次读到的数据不一致。不可重复度关注点在数据更新和删除,通过行级锁可以实现可重复读的隔离级别。

    例子:

    张三需要转正1000元,系统读到卡余额有2000元,此时张三老婆正好需要转正2000元,并且在张三提交事务前把2000元转走了,当张三提交转账是系统提示余额不足。

  • 幻读:指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。

    相对于不可重复读,幻读更关注其它事务的新增数据。通过行级锁可以避免不可重复读,但无法解决幻读的问题,想要解决幻读,只能通过Serializable隔离级别来实现。

    例子:

    张三老婆准备打印张三这个月的信用卡消费记录,经查询发现消费了两次共1000元,而这时张三刚按摩完准备结账,消费了1000元,这时银行记录新增了一条1000元的消费记录。当张三老婆将消费记录打印出来时,发现总额变为了2000元,这让张三老婆很诧异。

  • plus:不可重复读和幻读有点难理解:

    • 不可重复读是指事务A读取表中数据的时候,此时事务B对该数据进行了修改,导致事务A再次读取该数据时,发现不一样;两次读取相同的数据产生不同的结果
    • 幻读是指事务A在修改某表中的全部数据时,已经修改完毕,此时事务B又新插入一条记录,导致事务A再次读取该表中数据时,发现还有未修改的记录,产生了幻觉(其实事务A已经是修改完表中的数据了,新增的这条会让事务A误认为刚才的操作并没有修改完表中的记录);
    • 这里我们可以看下 上面不可重复读的介绍里面有个关注点:“不可重复度关注点在数据更新和删除”。幻读里面有个“幻读更关注其他事务的新增数据”
  1. 事务的隔离级别

    MySQL默认的是Repeatable-Read,避免脏读,不可重复读,允许幻读。

    MySQL事务和spring事务_第1张图片

spring事务

Spring事务传播:事务传播行为是指一个事务方法A被另一个事务方法B调用时,这个事务A应该如何处理。事务A应该在事务B中运行还是另起一个事务,这个有事务A的传播行为决定。

int PROPAGATION_REQUIRED = 0;
int PROPAGATION_SUPPORTS = 1;
int PROPAGATION_MANDATORY = 2;
int PROPAGATION_REQUIRES_NEW = 3;
int PROPAGATION_NOT_SUPPORTED = 4;
int PROPAGATION_NEVER = 5;
int PROPAGATION_NESTED = 6;

NOT_SUPPORTED = 4;
int PROPAGATION_NEVER = 5;
int PROPAGATION_NESTED = 6;


![image-20211228104924064](https://img-blog.csdnimg.cn/img_convert/f0d5e0a3b812323ae47fb156771026ac.png)

你可能感兴趣的:(mysql,mysql,spring,数据库)