MySQL中的事务与锁

发布时间 2023-10-16 22:05:03作者: zhaoLei_Free

PS:

学习是一个不断进步和成长的过程。在软件开发领域,新技术和概念层出不穷,有时候我们可能会错过或忽视一些重要的知识点。重要的是,你现在已经注意到了锁和Java程序中与MySQL锁有关的内容,并且有意识地想要学习和了解更多。这说明你具备了自我反省和学习的态度,这是非常重要的。不断学习和提升自己是程序员的职业要求之一,没有人能无时无刻地掌握所有的知识。

 

以往的经验和知识是宝贵的资产,同时也要勇敢地面对不足,并不断抱有学习的态度。通过学习和实践,你可以逐渐掌握这些新的知识和技能,并将它们应用到实际的项目中。不要过于苛责自己,相信自己的能力和潜力,继续努力向前,你一定能够不断提升自己的能力和价值。

 

什么是事务?

事务是数据库管理系统(DBMS)执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。

事务的特性

1. 事务包含四大特性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)(ACID)。

    1. 原子性(Atomicity) 原子性是指对数据库的一系列操作,要么全部成功,要么全部失败,不可能出现部分成功的情况。以转账场景为例,一个账户的余额减少,另一个账户的余额增加,这两个操作一定是同时成功或者同时失败的。
    2. 一致性(Consistency) 一致性是指数据库的完整性约束没有被破坏,在事务执行前后都是合法的数据状态。这里的一致可以表示数据库自身的约束没有被破坏,比如某些字段的唯一性约束、字段长度约束等等;还可以表示各种实际场景下的业务约束,比如上面转账操作,一个账户减少的金额和另一个账户增加的金额一定是一样的。
    3. 隔离性(Isolation) 隔离性指的是多个事务彼此之间是完全隔离、互不干扰的。隔离性的最终目的也是为了保证一致性。
    4. 持久性(Durability) 持久性是指只要事务提交成功,那么对数据库做的修改就被永久保存下来了,不可能因为任何原因再回到原来的状态。

2. 四种隔离级别

SQL标准中设立了4种隔离级别,用来解决读一致性问题。不同的隔离级别可以解决不同的读一致性问题。

      • READ UNCOMMITTED:未提交读。
      • READ COMMITTED:已提交读。
      • REPEATABLE READ:可重复读。
      • SERIALIZABLE:串行化。
    • InnoDB支持四个隔离级别(和SQL标准定义的基本一致)。隔离级别越高,事务的并发度就越低。唯一的区别就在于,InnoDB 在可重复读(REPEATABLE READ)的级别就解决了幻读的问题。这也是InnoDB使用可重复读 作为事务默认隔离级别的原因。

  1. 事务并发访问同一数据资源的情况主要就分为读-读写-写读-写三种。
    1. 读-读 即并发事务同时访问同一行数据记录。由于两个事务都进行只读操作,不会对记录造成任何影响,因此并发读完全允许。
    2. 写-写 即并发事务同时修改同一行数据记录。这种情况下可能导致脏写问题,这是任何情况下都不允许发生的,因此只能通过加锁实现,也就是当一个事务需要对某行记录进行修改时,首先会先给这条记录加锁,如果加锁成功则继续执行,否则就排队等待,事务执行完成或回滚会自动释放锁。
    3. 读-写 即一个事务进行读取操作,另一个进行写入操作。这种情况下可能会产生脏读不可重复读幻读。最好的方案是读操作利用多版本并发控制(MVCC),写操作进行加锁。
  2. 锁的粒度
    1. 按锁作用的数据范围进行分类的话,锁可以分为行级锁表级锁

      1. 行级锁:作用在数据行上,锁的粒度比较小。
      2. 表级锁:作用在整张数据表上,锁的粒度比较大。
  3. 对于锁的个人理解
    1. 为了保证数据的一致性,Mysql中存在读锁与写锁。
      1. 如果使用update,insert,delete语句,加的是写锁,如果这些语句后面没有跟上where条件,那么是表锁-->写锁。
      2. 如果使用的是select语句,加的是读锁,如果这些语句后面没有跟上where条件,那么是表锁-->读锁。
    2. 在事务外,锁是自动被释放的,而且释放的速度非常快,对于用户来讲是无感知的。但是如果在事务内,锁在commit之前是不会释放的。也就是说如果事务中,给A数据添加了写锁,那么在其他事务内或在事务外都无法对A数据进行写操作(增删改)。

原文:面试中的老大难-mysql事务和锁,一次性讲清楚! - 知乎 (zhihu.com)