mysql事务

以下内容都来源网上,再按自己的方式整理好让自己理解。

参考:来源一来源二来源三

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

   1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
   2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
   3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
   4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

 

 、事务的并发问题

  第一种解释

  1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
  2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
  3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

  第二种解释

  1、脏读:Mary的原工资为1000,财务人员将Mary的工资改为了8000,但未提交事务,与此同时,Mary正在读取自己的工资.Mary发现自己的工资变为了8000,欢天喜地!而财务发现操作有误,而回滚了事务,Mary的工资又变为了1000。

  2、不可重复读:在一个事务中前后两次读取的结果并不致,导致了不可重复读。在事务1中,Mary 读取了自己的工资为1000,操作并没有完成 。在事务2中,这财务人员修改了Mary的工资为2000,并提交了事务。在事务1中,Mary 再次读取自己的工资时,工资变为了2000。

  3、幻读:目前工资为1000的员工有10人。事务1,读取所有工资为1000的员工。共读取10条记录 。这时另一个事务向employee表插入了一条员工记录,工资也为1000。事务1再次读取所有工资为1000的员工,共读取到了11条记录,这就产生了幻像读。

  小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

 

 三、事务隔离级别

  1: read uncommitted。事务A对数据进行修改,但未提交。此时开启事务B,在事务B中能读到事务A中对数据库进行的未提交数据的修改。(这种方式也称为脏读)

  2 :read committed。事务A对数据进行修改,但还未提交。此时开启事务B,在事务B中不能读到事务A中对数据库的修改。在事务B还没有关闭时,此时事务A提交对数据库的修改。这时候,我们在事务B中,可以查到事务A中对数据库的修改。这时存在一个问题,我们在同一个事务中,对数据库查询两次,但两次的结果是不一样的。(这种方式称为不可重复读。)

  3 :repetition read。事务A对数据进行修改,但未提交,此时开启事务B,在事务B中不能读到事务A对数据库的修改。在事务A提交对数据库修改时,此时在事务B中,仍不能读到事务A对数据库的修改。(这种方式称为可重复读)但此时有一个弊端,比如我们在事务A中对数据库增加一条数据,id 为 n ,这时候我们在事务B中查询数据,此时查不到id为n的数据。但当我们在事务B中增加id为n的数据时,系统会提示id为n的数据已经存在,我们添加失败。但此时此刻,我们在事务B中仍不能查询到id为n的数据。这种方式存在一个幻读的概念。举个例子,(系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后关闭事务发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。)

  4 :serializable。在开启事务A时,会产生锁表,此时别的事务会等待,等事务A结束时才会开启。

  一般的数据库默认提供的是read committed隔离级别,如sqlserver2000;Mysql默认提供的是repetition read

 

  四、事务传播行为

  Spring 定义了如下七中传播行为,这里以A业务和B业务之间如何传播事务为例说明:

  ①、PROPAGATION_REQUIRED :required , 必须。默认值,A如果有事务,B将使用该事务;如果A没有事务,B将创建一个新的事务。

  ②、PROPAGATION_SUPPORTS:supports ,支持。A如果有事务,B将使用该事务;如果A没有事务,B将以非事务执行。

  ③、PROPAGATION_MANDATORY:mandatory ,强制。A如果有事务,B将使用该事务;如果A没有事务,B将抛异常。

  ④、PROPAGATION_REQUIRES_NEW :requires_new,必须新的。如果A有事务,将A的事务挂起,B创建一个新的事务;如果A没有事务,B创建一个新的事务。

  ⑤、PROPAGATION_NOT_SUPPORTED :not_supported ,不支持。如果A有事务,将A的事务挂起,B将以非事务执行;如果A没有事务,B将以非事务执行。

  ⑥、PROPAGATION_NEVER :never,从不。如果A有事务,B将抛异常;如果A没有事务,B将以非事务执行。

  ⑦、PROPAGATION_NESTED :nested ,嵌套。A和B底层采用保存点机制,形成嵌套事务。

  REQUIRED:表示业务方法需要在一个事务中处理,如果业务方法执行时已经在一个事务中,则加入该事务,否则重新开启一个事务。这也是默认的事务传播行为;
  NOT_SUPPORTED:声明业务方法不需要事务,如果业务方法执行时已经在一个事务中,则事务被挂起,等方法执行完毕后,事务恢复进行;(其他的传播行为省略,基本不用,一般的传播行为也是使用默认的:REQUIRED)

  

 

posted @ 2019-06-15 22:13  山水花草  阅读(184)  评论(0编辑  收藏  举报