谈谈你对事务的理解,事务的特性

Posted 只yao为你发光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谈谈你对事务的理解,事务的特性相关的知识,希望对你有一定的参考价值。

文章目录


前言

为什么要引入事务?
首先举个例子:比如我们熟知的购票系统,如果此时车票只剩一张,购票人A此时发现还剩一张票,于是他赶紧将这张票买了,但是他买完票之后数据库中还没来得及更新数据的时候,购票人B此时也发现还有一张票,当他也买了之后,给数据库发送减一的请求 ,此时就存在一张票同时被购票人A和购票人B持有,这显然不符合现实生活的逻辑,因此我们需要引入事务这个概念.

一、事务是什么?

事务就是由一个或者多个sql语句组成,它们之间是相互依赖的,如果其中一个sql语句执行失败或者发生错误,那么整个单元就会发生回滚,回到事务开始之前的样子.相反 ,如果没有一个sql语句发生错误,那么事务将顺利执行完成,将最终的数据写入数据库.

二、事务的特性

1. 原子性:

一个事务要么全部执行完成,要么在执行过程发生错误后产生回滚(回滚:数据恢复到事务开始之前,不产生改变),不会存在执行一半就结束的情况.

2.一致性:

一致性是事务开始到事务结束数据库的完整性没有被破坏,也可以理解为事务从一个正确的状态迁移到另一个正确的状态. 也就是所有写入的数据都符合之前设定的规则.
举个银行转账的例子: A有90块钱,他要向B转100块钱,如果可以转帐成功A余额为负数,我们银行是不允许账户余额为负数,所以转账就不能成立. 如果转账成功,虽然他没有破坏数据库的约束,但是他破坏了我们应用层的约束,所以事务发生了回滚,也可以说事务提供了一致性的保证.

3.持久性

持久性说的是事务一旦成功执行完成,也就是没有发生回滚,那么它对数据的修改就是永久的,即使现在系统发生故障也不会丢失数据.

4.隔离性

4.1无隔离性会出现的情况

4.1.1 脏读

所谓脏读就是在事务没有完成时,读到了数据库中正在修改的内容
举例说明:

小明的老师正在登成绩,小明的成绩是50分,结果老师不小心写成100分了,但是老师这会还没有公布成绩;
小明这时刚好看到老师给自己了100分,于是很高兴;
老师发现自己写错了,然后将100分修改成了50分;
此时就出现了脏读现象:小明的成绩是50分,但是由于没有事务来保证,小明在事务完成的中间就可以获取到数据
导致出现了偏差.

解决方法:

给写操作加上锁,在写操作没有完成时,无法进行读操作.

4.1.2 不可重复读

不可重复读产生的原因就是,在写操作完成后,进行读操作,读操作还没有完成,又有用户调取了写操作,写操作已经完成,然后立马又进行读操作,发现两次读取的结果不相同;
举例说明:

老师登记小明的成绩为50分,然后全班同学相继来看,在看的过程中老师发现成绩不对
然后给小明改成100分,这时刚才看过分数的小明忘记自己的分数了,回过头来看的时候
发现自己的成绩是100分,和之前的结果发生了冲突

解决方法:

给读也加上锁,读是时候不能写,写的时候不能读.

4.1.3幻读

幻读产生的原因和不可重复读很像,不可重复读是改变数据的值,而幻读是插入新的元素,在两次读之间可以插入新的数据,导致两次查询结果个数不一致.
举例说明:

在一个班级有10个人,老师先看了一下班级有10个人,由于此时读和写操作都加锁了,所以老师是能记住每个人的信息;
但是在老师读的过程中,教务处又给这个班级新加了一个学生,导致老师这次不知道;
老师在点完名之后,里面又获取到锁,再次进行点名,此时发现班级竟然是11人;
此时就产生了幻读.

解决办法:

让所有的事务都是串行执行,避免了并发执行就可以避免幻读现象甚至避免不可重复读和脏读.

4.2数据库的隔离级别

4.2.1读未提交(read uncommitted)

如果一个事务已经开始了写操作,那么其他的事务就不能进行写操作,得等前一个事务写操作结束才可以继续抢占式执行写操作;

解决的数据更新丢失,但是会出现脏读,不可重复读,和幻读问题

4.2.2 读已提交(read committed)

如果一个事务已经开始了写操作,那么将不能执行读操作,得等写操作完了才能进行读操作,但是在读操作的时候可以进行写操作.

解决了数据更新丢失和脏读问题,但是会出现不可重复读和幻读问题

4.2.3 可重复读(repeatable read)[mysql默认隔离级别]

如果一个事务开始了写操作,那么它将不能执行读操作,如果执行了读操作,那么他也将不能执行写操作,换句话来说就是将读操作和写操作捆绑起来变成原子操作;
解决了数据更新丢失,脏读和不可重复读,但是会出现幻读问题

4.2.4 可串行化(serializable)

按照最严格的事务隔离,事务只能一个接一个的执行,完全丢弃了并行执行. 串行化是最高的事务隔离级别,同时也是代价最高的,执行效率是最慢的,性能很低,所以一般很少使用.
解决了所有问题 : 更新丢失,脏读,不可重复读和幻读
用一张表格来汇总一下:

以上是关于谈谈你对事务的理解,事务的特性的主要内容,如果未能解决你的问题,请参考以下文章

谈谈你对事务的理解,事务的特性

面试官:谈谈你对分布式事务的理解?

陌陌面试官:谈谈你对MySQL中事务和锁的理解?

详解 MyBatis 事务管理,彻底颠覆你对事务的理解!

详解 MyBatis 事务管理,彻底颠覆你对事务的理解!

面试官:请用通俗易懂的方式谈谈你对Spring的理解