来聊一聊MySQL中事务的相关问题

这里是MySQL的基础内容,我将他们的链接放到下面,方便大家阅读

mysql中DDL的操作方法
mysql中的DML操作
点了五根烟,终于把MySql中查询操作(DQL)搞懂了!
MySql中数据完整性彻底解析
MySQL多表查询一遍打通
MySQL中子查询看不明白?那就得好好练
一些我们在MySQL中常用的函数
让我们来聊聊MySQL中的权限操作
MySQL中关于视图的一点两点
MySQL中的存储过程一路通关!
MySQL中索引一遍过

一、什么是事务

  1. 事务是不可分隔的操作,假设该操作有ABCD四个操作。若ABCD四个步骤都成功完成,则认为i事务完成;若ABCD中任意一个步骤操作失败,则认为事务失败。
  2. 每条sql语句都是一个事务。
  3. 事务只对DML语句有效,对于DQL无效。

二、事务的ACID

  1. 原子性(Atomicity)

    原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。

  2. 一致性(Consistency)

    一致性是指事务必须是数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态,让数据保持一定上的合理。例如:一个商品数量减1,对应用户的购物车中商品加1。

  3. 隔离性(Isolation)

    一个事务内部的操作及使用的数据对并发的其他事务是隔离的。

  4. 持久性(Durability)

    事务一旦提交,对对数据库的改变是永久的。

三、事务使用

  1. 开启事务 start transaction
  2. 回滚事务 rollback
  3. 提交事务 commit
CREATE TABLE zs_sccount (
	name varchar(30),
	money DECIMAL
);
CREATE TABLE ls_account (
	name varchar(30),
	money DECIMAL
);
start transaction;		//开启事务
update zs_account set money = money - 2000;
update ls_account set money = money + 2000;
commit; 				//提交事务

事务在开始后,如果不进行提交就可以将事务回滚,并且在提交之前,别人不能查询出事务的操作(隔离性)。所有语句全部执行完毕,没有发生异常,提交事务之后,更新到数据库当中。

事务的回滚(rollback)当遇到突发情况,撤销执行的sql语句。
在这里插入图片描述

四、事务隔离等级

  1. Read uncommitted 读未提交

    MySQL数据库默认的隔离级别。该级别解决了READ UNCOMMITTED隔离级别导致的问题。它保证同一事务的多个实例在并发读取事务时,会“看到同样的”数据行。不过,这会导致另外一个棘手问题“幻读”。InnoDB和Falcon存储引擎通过多版本并发控制机制解决了幻读问题。

  2. Read committed 不可重复读

    大多数数据库系统的默认隔离级别(但是不是MySQL的默认隔离级别),满足了隔离的早先简单定义:一个事务开始时,只能“看见”已经提交事务所做的改变,一个事务从开始到提交前,所做的任何数据改变都是不可见的,除非已经提交。这种隔离级别也支持所谓的“不可重复读”。这意味着用户运行同一个语句两次,看到的结果是不同的。

  3. Repeatable read 可重复读

    在这个隔离级别,所有事务都可以“看到”未提交事务的执行结果。在这种级别上,可能会产生很多问题,除非用户真的知道自己在做什么,并有很好的理由选择这样做。本隔离级别很少用于实际应用,因为它的性能也不必其他性能好多少,而别的级别还有其他更多的优点。读取未提交数据,也被称为“脏读”

  4. Serializable 串行化

    该级别是最高级别的隔离级。它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简而言之,SERIALIZABLE是在每个读的数据行上加锁。在这个级别,可能导致大量的超时Timeout和锁竞争Lock Contention现象,实际应用中很少使用到这个级别,但如果用户的应用为了数据的稳定性,需要强制减少并发的话,也可以选择这种隔离级

五、事务并发

1.脏读

我们先来看一个例子:老板要给程序员发工资,程序员的工资是3.6万/月。但是发工资时老板不小心按错了数字,按成3.9完/月,该钱已经打到程序员的户口,但是事务还没提交,就在这时,程序员去看自己这个月的工资,发现比往常多了3千元,意味涨工资了 非常开心。但是老板及时发现了不对,马上回滚差点就提交了的事务,将数字改成3.6万再提交。实际上程序员这个月的二公子还是3.6万,但是程序员看到的时3.9万元。他看到的是老板还没提交事务的数据,这就是脏读。

解决办法:Read committed! 读提交,能解决脏读问题。

数据库的隔离性如果设置为read uncommitted,即一个事务可以读取另一个未提交事务的数据,这样就会出现上述出现的情况。而read committed是一个事务要等另一个事务提交后才能读取数据,而回滚的数据别人并不能看见,就可以很好的解决脏读的问题。

2.不可重复读

我们还是通过一个例子来看:程序员拿着工资卡(卡里有3.6万),当他消费买单时(程序员事务开启),收费系统实现检测到他卡里有3.6万。就在这时,程序员老婆要把钱全部转走,并且提交。收费系统准备扣款时,再检测卡里的金额发现已经没钱了。程序员很郁闷,命名卡里是有钱的。

这就是一个事务范围内两个相同的查询返回了不同数据,这就是不可重复度。

解决办法:Repeatable read

3. 重复读

重复度也就是不可重复读的解决办法,我们可以这样理解:程序员拿着工资卡(3.6万),当他消费时(事务开启,不允许其他事务的UPDATE修改操作),收费系统事先检测到他的卡里有3.6万,这个时候他的老婆就不能转出金额,接下俩就可以正常扣款了。

4. 幻读

哈哈哈,再来个例子。程序员某一天去消费,花了2千元,然后他的老婆去查看他今天的消费记录(妻子事务开启),看到确实花了2千,就在这个时候,程序员花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当妻子打印程序员的消费记录时(妻子事务提交),发现花了1.2万元,似乎出现了幻觉,这就是幻读。

解决办法:运用Serializable这种事务隔离,但这种隔离级别效率低下,比较消耗数据库性能,一般不使用。

六、对应关系

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值