事务的本质和死锁的原理・改

由于一些错误操作和被爬的原因,我重新整理了 上一篇文章https://www.cnblogs.com/klarck/p/13630990.html

前言、事务方块

在我的理解,事务是这个形状的

事务的本质和死锁的原理・改
x轴是可以锁定的资源,y轴是函数执行时间,
事务随着时间的流逝向下降落,
当恰好与x轴接触时资源被锁定,当恰好不再与x轴接触时资源解除锁定,从恰好与x轴接触到恰好不再与x轴接触这个时间段就是事务的执行时间。
这里的耗时五秒是夸张的写法,通常情况下单位是毫秒级甚至微妙级,这里使用秒作为单位是为了凸显现象
上图是函数a的事务形状,命名 【 事务方块】
 @Transactional
 public void a(){
   //对A表修改,耗时5秒
 }

一、多事务

当一个函数调用多个子函数且都是被事务注解的函数时情况是

事务的本质和死锁的原理・改

上图是对于函数abc调用时,a函数、b函数、c函数的事务形状

public void abc(){
    this.a(){}
    this.b(){}
    this.c(){}
}
@Transactional
public void a(){
    //对A表修改,耗时五秒
}
@Transactional
public void b(){
    //对B表修改,耗时五秒
}
@Transactional
public void c(){
    //对C表修改,耗时五秒
}

当abc函数开始执行时,先调用a函数,先锁定a表,
当a函数结束执行,a表解锁,同时b函数开始执行,b表锁定,
当b函数结束执行,b表解锁,同时c函数开始执行,c表锁定。
相当于下图的三个事务方块联合且相对位置固定一起下落,总耗时十五秒

事务的本质和死锁的原理・改

如果并发请求两次abc函数,事务方块如图

事务的本质和死锁的原理・改

首先a表被请求一锁定五秒后解锁,再马上被请求二锁定五秒,
然后b表也被请求一锁定五秒后解锁,再马上被请求二锁定五秒,
最后c表也被请求一锁定五秒后解锁,再马上被请求二锁定五秒,
而请求一在解锁表a后紧接着又锁定了表b五秒,同时表a再被请求二锁定五秒
依此类推,请求二都在请求一解锁对应的表后锁定该表,
那么总运行时间二十秒

二、大事务

@Transactional
function abc(){
     this.a(){}
     this.b(){}
     this.c(){}
}
public void a(){
    //对A表修改,耗时五秒
}
public void b(){
    //对B表修改,耗时五秒
}
public void c(){
    //对C表修改,耗时五秒
}

其中abc函数有注解,而子函数a、b、c没有注解,事务形状如图

事务的本质和死锁的原理・改

a、b、c三个颜色的方块是结合在一起的,必须一起执行,实际上就是事务原子性的表象,那么a表被锁定十五秒,b表被锁定十秒,c表被锁定五秒
若也同时并发两次abc函数则总耗时三十秒,容易发现事务越大,耗时越长;本来在多事务时被锁定五秒的a表,被锁定了十五秒。
在这个abc函数中,事务对表的锁定是懒锁定的情况,
就是说,当abc函数中
a函数开始执行时,只锁定了a表,当a函数执行完成,
b函数开始执行锁定b表,此时不解锁a表,当b函数执行完成,
c函数开始执行锁定c表,此时不解锁a、b两个表,当c函数执行完成,同时解锁a、b、c三个表。
这就导致了死锁的出现

三、死锁

有如下两个函数ab和ba

 @Transactional
 public void ab(){
   this.a(){}
   this.b(){}
 }
 @Transactional
  public void ba(){
   this.b(){}
   this.a(){}
 }

当ab和ba函数同时被执行时,事务方块类似下图,但不完全

事务的本质和死锁的原理・改

当ab和ba函数同时被执行时,ab锁定a表,ba锁定b表,
当ab执行完a函数请求锁定b表时,同事ba也执行完了b函数请求锁定a表,
但ab没有解开对a表的锁定,ba也没有解开对b表的锁定,那么相互等待对方解锁,出现死循环,这就是死锁。
所以减少死锁出现的几率的办法是减小事务方块的大小,即减小事务方块消耗的时间或减小事务方块锁定的资源【表或行】
所以行级锁不易出现死锁,表级锁易出现死锁,是因为行级锁资源占用小,当时间相同时,行级锁的事务方块小。
当表的主键是整型的自增ID时,则相当于把事务可锁定资源从一个资源【表】分割成了2147483647份的资源【行】,可见使用行级锁时事务方块明显变小。

四、名称来历

事务方块的名字来历是一次研究死锁时联想到俄罗斯方块的情形与事务的情形类似,俄罗斯方块是为了找一个位置放置方块,而事务方块是为了找一个时空缝隙让方块执行通过,目的不同。

事务的本质和死锁的原理・改

【网络图片侵删】

Original: https://www.cnblogs.com/klarck/p/13658868.html
Author: 一剑破万法
Title: 事务的本质和死锁的原理・改

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/591708/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • MySQL45讲之主备数据一致性

    本文主要介绍 MySQL 主备数据同步的重要日志 binlog 的三种格式,和双 M 结构的循环复制问题。 binlog三种格式 1. statement格式 直接存储了执行的 S…

    数据库 2023年5月24日
    096
  • PHP最全编码规约

    1.1 标签 (1)【强制】PHP 程序可以使用或来界定 PHP 代码,在 HTML 页面中嵌入纯变量时,可以使用这样的形式,不可使用其他的标签变种。 正例: (2)【强制】纯 P…

    数据库 2023年6月14日
    0113
  • LeetCode 344. 反转字符串

    编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 //输入一个字符串,输出它的倒序字符串 input: Hello output: olleH …

    数据库 2023年6月11日
    084
  • 创建Django项目

    2022-09-24 在创建Django项目时,出现了 错误,查了一下,发现要创建一个Django项目,需要先使用命令: python -m pip install pytz 安装…

    数据库 2023年6月14日
    079
  • MySQL数据库的创建、删除和备份

    总结MySQL数据库的创建、删除和备份操作 MySQL数据库的创建、删除和备份 数据库的创建 //使用指令创建数据库 CREATE DATABASE yjh_db01; //创建一…

    数据库 2023年6月16日
    081
  • Java压缩图片

    压缩图片 一、压缩原理 一张原始图像(1920×1080),如果每个像素32bit表示(RGBA),那么,图像需要的内存大小1920x1080x4 = 8294400 B…

    数据库 2023年6月6日
    084
  • Win10系统链接蓝牙设备

    进入设备界面,删除已有蓝牙,如果蓝牙耳机已经链接其他设备,先断开链接 点击添加蓝牙或其他设备 Original: https://www.cnblogs.com/itcaimeng…

    数据库 2023年6月11日
    092
  • 模板语法之标签

    语法 {% 开始标签 %} …. {% 结束…

    数据库 2023年6月14日
    0128
  • MySQL实战45讲 16

    16 | “order by”是怎么工作的? 以市民表为例,假设要查询城市是”杭州”的所有人名字,并且按照姓名 排序返回前 1000…

    数据库 2023年6月14日
    097
  • SpringBoot邮件报警

    SpringBoot邮件报警 一、介绍 邮件报警,大体思路就是收集服务器发生的异常发送到邮箱,做到服务器出问题第一时间知道,当然要是不关注邮箱当我没说 (1)、引入依赖 <d…

    数据库 2023年6月6日
    0113
  • 13 数组有没有 length()方法 String 有没有 length()方法

    数组没有length()方法,有length属性; String有length()方法。 注意:在JavaScript中,获得字符串长度是通过length属性得到的,这一点请不要和…

    数据库 2023年6月6日
    085
  • MySQL 回表

    MySQL 回表 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。 一、简述 回表,顾名思义就是回到表中,也就是先通过普通索引扫描出数据所在的行,再通过行主键ID 取出索引中未包含…

    数据库 2023年6月14日
    074
  • 【JDBC】笔记(3)— 提高用户登录功能的安全性 (javaSE+MySQL+JDBC)[ 应用 PreparedStatement ]

    一.实现功能: 1.解决”应用Statement的登录系统”存在的SQL注入问题2.用户信息表+—-+———…

    数据库 2023年5月24日
    086
  • 常用API(Java)

    Object 场景:当我们使用toString方法想要输出对象变量时,官方提供的toString方法会直接输出对象所在的地址,而不是我们想要的对象变量,所以我们要把toString…

    数据库 2023年6月16日
    088
  • 2022-8-17 mysql 第三天

    子查询 按照结果集的行列数不同,子查询可以分为以下几类: 标量子查询:结果集只有一行一列(单行子查询) 列子查询:结果集有一列多行 行子查询:结果集有一行多列 表子查询:结果集多行…

    数据库 2023年6月14日
    076
  • Maven配置私有仓库

    前言 当公司或个人具有自己独有的jar时,不想公开,一般就会放在自己的私有Maven仓库中,在项目中需要引用,此时就需要将公司私有仓库配置到maven当中,一般我们的maven配置…

    数据库 2023年6月16日
    0142
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球