MySQL性能优化——事务管理基本概念

本教程仅为本人的学习笔记,如有错误,请指出,欢迎观看~

一.事务管理的概念

事务的概念: 一个事务是对数据库进行读和写的一个序列。

事务管理的目的:
1、为数据库操作提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
2、当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法, 以防止彼此的操作互相干扰。

总结来说:
事务的目的就是要提供3种方法: 1.失败恢复方法2.保持一致性的方法3.操作隔离的方法。

成功情况下将数据永久保存,失败情况下将数据恢复到正常状态,保证数据一致性,并且保证数据在并发状态下不会互相影响。

MySQL事务管理的基本语句:

//开始事务
start transation 

//提交事务
commit

//事务回滚
rollback

二.事务的四大特性(ACID)

原子性(Atomicity):

事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。

举例:
假如用户A订购商品,必须保证余额扣除的操作和增加订单的操作一次性全部完成,如果其中发生错误,需要保证所有操作都退回到未操作之前,否则就可能出现越扣除而商品消失的情况。

一致性(Consistency):
事务应确保数据库的状态从一个一致状态转变为另一个致状态。一致状态的含义是数据库中的数据应满足完整性约束。

隔离性(Isolation):
多个事务并发执行时, 一个事务的执行不应影响其他事务的执行

举例:
用户A下订单,数据库在订单表中插入数据,同时用户B需要对对此订单进行操作(AB用户并发操作),紧接着扣操作发生异常,订单表中订单被删除(事务回滚),用户B并不知情,使用已删除的数据对数据库进行操作,就会导致操作失败,甚至使系统异常。

持久性(Durability):

当事务被提交后,他对数据库的改变将永久的存储到数据库中。

举例:
用户完成下单操作,数据库中插入了相应数据,事务提交后,即使服务器发生故障,也不会影响已购的商品订单。

三、并发状态下的常见异常

当多个用户同时访问操作同一数据是,就容易发生以下异常:

回滚丢失(第一类更新丢失):

由于事务导致的数据丢失。

举例:
用户A充值余额,原余额10元,充值后为15元,此时B对A进行充值操作,但是由于额外错误,操作被回滚,直接将余额回滚的10元,导致A的充值丢失。

覆盖丢失(第二类更新丢失):

由于提交事务导致之前的更新被覆盖导致的数据丢失。

举例:
用户A为账户充值,充值流程执行时,先查询余额为10元,同时用于B给用户A进行充值,由于用户A的充值流程发生意外卡顿,导致B后开始充值但先完成,余额为20元,但是A的充值命令执行时并没有刷新余额,在10元的基础上充值5元,覆盖了B的充值,最后余额为15元,导致B的充值丢失。

脏读:

一个事务读取到了另一个事务未提交的数据。

举例:

用户A下订单,数据库在订单表中插入数据,同时用户B需要对对此订单进行操作(AB用户并发操作),紧接着扣操作发生异常,订单表中订单被删除(事务回滚),用户B并不知情,使用已删除的数据对数据库进行操作,就会导致操作失败,甚至使系统异常。

上方例子,A并没有提交事务但是数据已经被B读取到了,此时就是一个脏读操作,由于A并没有提交事务,此时很容易因为A的回滚操作导致B已读取到的数据无效。

不可重复读:

在一个事务内的不同位置查询同一条数据,结果有是不相同的。

举例:
用户A余额为10元,在一个事务内,刚开始查询A的余额为10元,在A的事务提交之前,用户B对A进行了充值操作,此时可能在最后一条语句再次查询余额,查询为充值后的15元。

幻读:

幻读与不可重复读类似,但幻读主要体现在数据量上的不相同,而不可重复读主要是数据本身的不相同。

举例:
用户A的充值记录共有10条,可能在一个操作更开始执行时查询A有10条记录,在程序执行完成期间内(事务结束之前),B对A同时进行了充值操作,则可能导致A在最后一条语句再次查询充值记录,为11条。

四、事务隔离级别

为了解决并发操作是事务的异常(上方异常),所以需要将事务间操作进行隔离,也体现了ACID原则中的隔离性。

读未提交(Read Uncommitted):

并行操作时,其中一个事务可以读取到另外一个事务还没提交的内容。

读已提交(Read Committed):

并行操作时,一个事务只能读取到另一个事务已经提交的部分。

可重复读(Repeated Read):

在一个事务内的任何位置,都可以保证读取到的数据一致,不会出现数据不同的情况(此时如果另一个事务提交查询的数据,会先等待当前事务完成)。

串行化(Serializable):

直接严格控制事务,不可进行并发,完全串行操作。

不同的隔离级别可以防止不同的异常发生。
在这里插入图片描述

注意:MySQL的默认的事务隔离级别为可重复读。SQLServer默认为度已提交,一般来说,越高级的隔离级别效率越低,读未提交安全性差,一般不用,串行化效率过低,一般不用。

五,设置MySQL事务隔离级别

查询事务隔离级别语句:

 select @@session.tx_isolation;

在这里插入图片描述
可以看到mysql数据库默认的事务隔离级别为可重复读。

**设置事务隔离级别:**
//设置read uncommitted级别:
set session transaction isolation level read uncommitted;

//设置read committed级别:
set session transaction isolation level read committed;

//设置repeatable read级别:
set session transaction isolation level repeatable read;

//设置serializable级别:
set session transaction isolation level serializable;

设置后可进行查询:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42628989/article/details/106765377