MySQL高级使用--事务和锁【知识点整理】

 

目录

1.事务

1.0.事务开始和结束节点

1.1.事务的语法

1.2.事务的ACID属性

1.3.事务的并发引起的问题

1.4.事务隔离级别

1.4.1.事务隔离级别

1.4.2.查看设置当前会话中事务的隔离级别

1.4.3."读未提交"隔离级别--脏读场景

1.4.4."读已提交"隔离级别-消除脏读但出现不可重复读场景

1.4.5.'可重复读'隔离级别--消除不可重复读问题,但出现幻读场景

1.4.6.顺序读(SERIALIZABLE)

1.5.不同隔离级别的锁的情况

1.6.隐式提交

1.7.JDBC中事务应用

1.8.Savepoints接口

1.9.事务案例:转账

1.9.事务总结

2.常用SQL语句练习整理


1.事务

事务(Transaction)
  • 是数据库操作的一个执行单元,管理一组的SQL语句,要么同时执行成功,要么同时执行失败。一个逻辑工作单元要成为事务,必须满足所谓的ACID
  • (1) 事务的 语法
  • (2) 事务的特性
  • (3) 事务并发问题
  • (4) 事务隔离级别
  • (5) 不同隔离级别的锁的情况(了解)
  • (6) 隐式提交(了解)

1.0.事务开始和结束节点

事务开始于

  • - 连接到数据库上,并执行一条DML语句insertupdatedelete
  • - 前一个事务结束后,又输入了另一条DML语句

事务结束于

  • - 执行commitrollback语句。
  • - 执行一条DDL语句,例如create table语句,在这种情况下,会自动执行commit语句。
  • - 执行一条DDL语句,例如grant语句,在这种情况下,会自动执行commit
  • - 断开与数据库的连接
  • - 执行一条DML语句,该语句却失败了,在这种情况中,会为这个无效的DML语句执行rollback

1.1.事务的语法

  • 事务在之前增删改查中都是存在的,那些sql并不需要去关注事务,事务会自动的进行提交,下面通过语句方式进行事务的管理
  • 事务主要包含三个操作:启动-提交-回滚
1. start transaction; begin; 启动
2. commit ; 提交, 使得当前的修改确认
3. rollback ; 回滚, 使得当前的修改被放弃,事务在未提交前都可以回滚

注意:当前数据库的引擎必须是innoDB,其它类型不支持事务

1.2.事务的ACID属性

1. 原⼦性(Atomicity)
  • 表示一个事务内的所有操作是一个整体,要么全部成功,要么全部失败
2. ⼀致性(Consistency)
  • 表示一个事务内有一个操作失败时,所有的更改过的数据都必须回滚到修改前状态
  • 比如:如果从A账户转账到B账户,不可能因为A账户扣了钱,⽽B账户没有加钱。
3. 隔离性(Isolation)
  • 事务的隔离性是指在并发环境中,并发的事务是互相隔离的。也就是说,不同的事务并发操作相同的数 据时,每个事务都有各自完整的数据空间。比如某个时间点有100人转账,这些数据不会出现交错现象。
  • 事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修
    改它之后的状态,事务不会查看中间状态的数据。
  • ⼀个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务是不能互相干扰的隔离性分4个级别,下面会介绍。

4. 持久性(Duration)

  • 事务的持久性是指事务⼀旦提交后,数据库中的数据被永久的保存下来。即使服务器系统崩溃或服务器宕机等故障。只要数据库重新启动,那么一定能够将其恢复到事务成功结束后的状态

 

1.3.事务的并发引起的问题

在不考虑事务隔离情况下

脏读:
  • 事务B读取到事务A没有提交的数据, 事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到数据是脏数 据。
  • t1事务修改了数据,但没有提交,事务t2读取了这个修改后数据,这时事务t1回滚撤销了修改,commit提交数据,此时事务t2再次读取这个数据是修改前的数据,在同一个事务中是不允许前后数据不一致的
 
不可重复读:
  • 同⼀条读取命令返回不同的结果集(一般在更新操作会出现不可重复读情况.事务 A 多次读取同一数据,事务 B 在事务A 多次读取的 过程中,对数据做了更新并提交,导致事务A多次读取同一数据时,结果不一致。
  • 在一个事务的两次查询之中数据在内容上不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。
幻读:
  • 重复查询的过程中,数据 就发⽣了量的变化(主要在insert, delete操作中会出现幻读
  • 在一个事务的两次查询中数据在量上不一致,例如有一个事务查询了几列数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

不可重复读和幻读区别:

  • 前者考虑的是数据内容上的变化,后者考虑的是在量上的变化

1.4.事务隔离级别

  • 针对事务的并发产生的问题,解决方案--事务隔离

1.4.1.事务隔离级别

  • 读未提交:该级别允许脏读取、不可重复读取和幻读取
  • 读已提交:该级别解决了脏读,但是解决不了不可重复读取
  • 可重复读:该级别解决了脏读取和不可重复读取,但可能出现幻读
  • 4种事务隔离级别从上往下,级别越高,并发性越差,安全性就越来越高。 ⼀般数据默认级别是 读以提交或可重复读

1.4.2.查看设置当前会话中事务的隔离级别

  • mysql> set session transaction isolation level read uncommitted;
  • select @@tx_isolation; -- mysql8以前使用该查询
  • select @@transaction_isolation;-- mysql8及以后使用

1.4.3."读未提交"隔离级别--脏读场景

1. 读未提交(READ_UNCOMMITTED)

  • 读未提交,该隔离级别允许脏读取,其隔离级别是最低的。换句话说,如果一个事务正在处理某一数 据,并对其进⾏了更新,但同时尚未完成事务,因此还没有提交事务;而以此同时,允许另一个事务也 能够访问该未提交的数据

脏读示例:

在事务 A 和事务 B 同时执行时可能会出现如下场景:

  • 以事务A角度,它脏读取了没有提交的余额0(脏数即修改后的数据)后冲了500元,提交事务后,事务A 查询余额应该为500元才对,最后查询结果是1500,事务A并不知道事务B回滚了1000。请看T5时间点,事务A此时查询的余额为0,这个数据就是脏数据,他是事务B 造成的, 很明显是事务没有进行隔离造成的。

根据上面场景测试脏读

  • 首先两个都要设置会话隔离级别为“读未提交”,

 

  • 然后事务B回滚rollback后,事务A冲了500并提交数据后,查询余额事务A认为是500,而实际显示出来的是1500.

1.4.4."读已提交"隔离级别-消除脏读但出现不可重复读场景

1.读已提交(READ_COMMITTED)
  • 不同的事务执行的时候只能获取到已经提交的数据。(像上面在事务B中的余额0没有提交,被事务A脏读取了,导致事务A认为没钱了,实际上事务B回滚1000) ,这样就不会出现上面的脏读的情况了。 但是在同一个事务中执行同一个读取,结果不一致。可是解决了脏读问题,但是还是解决不了不可重复读问题。

2.设置"读已提交"隔离级别消除脏读取

  • 事务A只能读取已提交数据,若事务B取走1000元但没提交数据,那么此时事务A读取的还是原来提交的1000元,消除了脏读取,保证了数据的一致性。
  • 案例还是按照脏读场景步骤来写,只是升级了事务的隔离级别。
 
 
 
3.不可重复读场景--隔离级别为读已提交
 

  • 上述流程发现,事务A其实除了查询两次以外,其它什么事情没做,结果钱就从1000变成0了,这就是不可重复读的问题
  • 事务 B 在事务A 多次读取的 过程中,对数据做了更新并提交,导致事务A多次读取同一数据时,结果不一致。这时不合理。

1.4.5.'可重复读'隔离级别--消除不可重复读问题,但出现幻读场景

1.可重复读(REPEATABLE READ)
  • 可重复读就是保证在事务处理过程中,多次读取同一个数据时,该数据的值和事务开始时刻是一致的,除非数据是被本身事务自己所修改
  • 因此该事务级别限制了不可重复读和脏读,但是有可能出现幻读的数据
幻读问题
  • 幻读就是指在一个事务的两次查询中数据在量上不一致

2.设置"可重复读"隔离级别消除不可重复读取问题

  • 只是提高了隔离级别,场景还是上面的不可重复读的场景

 

3.幻读场景--当前隔离级别 可重复读

 

 

 

 

  • 为了保证幻读一定不会出现,可以对数据进行序列化隔离级别设置,在对表的时候就已经上锁了。

1.4.6.顺序读(SERIALIZABLE

  • 顺序读是最严格的事务隔离级别。它要求所有的事务排队顺序执行,即事务只能一个接一个地处理,不 能并发

1.5.不同隔离级别的锁的情况

事务的隔离级别能实现隔离的根本原因

  • 每次设置隔离级别后,对数据上了锁。
  • 行级锁:每一行数据都加锁。
  • 间隙锁:保证某个间隙内的数据在锁定情况下不会发生任何变化。

锁的情况:

  • 1. 读未提交(RU: 有行级的锁,没有间隙锁。它与RC的区别是能够查询到未提交的数据。
  • 2. 读已提交(RC):有行级的锁,没有间隙锁,读不到没有提交的数据。
  • 3. 可重复读(RR):有行级的锁,也有间隙锁,每次读取的数据都是一样的,并且没有幻读的情况。
  • 4. 序列化(S):有行级锁,也有间隙锁,读表的时候,就已经上锁了

1.6.隐式提交

  • 隐式提交:指不需要通过指令来提交事务。数据库默认的是隐式提交(增删改查时)

1.7.JDBC中事务应用

https://blog.csdn.net/qq_40454863/article/details/113963196

1.8.Savepoints接口

https://blog.csdn.net/qq_40454863/article/details/113963196

1.9.事务案例:转账

https://blog.csdn.net/qq_40454863/article/details/113963196

1.9.事务总结

2.0.对Mysql的锁了解

  • 当数据库有并发事务的时候,可能会产生数据的不一致,这时候需要一些机制来保证访问的次序,锁机制就是这样的一个机制。

 

 

 

 

 

 

 

 

 

MySQL基本使用及单表的增删改查语句

https://blog.csdn.net/qq_40454863/article/details/113809607

常用SQL语句练习整理

https://blog.csdn.net/qq_40454863/article/details/113925975

数据库的设计、表的约束(完整性)、多表设计与查询

https://blog.csdn.net/qq_40454863/article/details/114067770

Java操作数据库详解--JDBC

https://blog.csdn.net/qq_40454863/article/details/113963196

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值