背景:
第一次接触事务是在mysql的:特性中也就是ACID的底层逻辑:
1. 什么是事务:
事务就是单次程序执行的过程中,要么完全成功,要么完全不执行;
表示就是并发控制的基本单位,要满足一个操作是事务;
1、事务处理(事务操作):保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务回滚(rollback)到最初状态。
1.1必须具备以下四种特性简称(ACID):
A:原子性(Atomicity)
此操作是一个原子性不可以分割的,事务中的操作要么都不做,要么就全做。
C:一致性(Consistency)
事务执行的结果必须是从数据库从一个一致性状态转换到另一个一致性状态,保证数据转化状态一致。
I:隔离性(Isolation)
一个事务的执行不能被其他事务干扰
D:持久性(Durability)
一个事务一旦提交,它对数据库中数据的改变就应该是永久性的
2.事务的隔离级别:
百度百科:
在并发读取数据的过程中,为了保证数据的一致性(完整),提出了事务的隔离级别;
数据在并发读取过程中会发生数据不完整的情况,然后提出了事务的隔离级别;
也就是说多人在使用数据库,但是在操作数据库的过程中,需要单独隔离起来,但是具体的级别得配置;
场景:
在电商平台买东西的过程中,首先使用的是一个下订单,锁库存的操作,
创建订单–>订单明细中添加了买的东西—>库存表修改—>销量增加;
3.mysql 的事务
默认是自动提交事务, 一个sql语句代表一个事务,遵循ACID 的特性,然后我们开始使用具体的操作;
因为默认是自动提交的,所以我们首先要取消自动提交;
手动提交事务;
方式一:
set autocommit=false;
保持的数据链接这次要手动进行提交
//这次链接的过程中数据,我们数据操作要是没有具体的提交,我们数据库不会保存的;
set autocommit=false;
要是直接对数据进行操作,但是当前的链接是自动提交是取消的状态,我们是将数据不会保存更改的;
这个设置只生效于当前的链接;
方式二:
上述的表示一次链接的过程中,都需要自己本地的手动提交,但是这样的话效率会很受影响;
我们可以使用transaction来解决这个问题,
transaction 可以更加灵活的方式表述 ,当数据开始以这种形式
比如:
start transaction
。。。。。
commit;rockback;
上述是一个事务的提交状态
要是直接写sql则表示,自动提交
表述当前的操作既可以提交,也可以回滚
4.mysql 的隔离级别:
对于共享数据,比如同一个表中,同一个表中的同一条记录,被各个事务共同操作和使用,在这个过程中,为了保证数据的完整性,提出了隔离级别的概念;
(1)READUNCOMMITTED( read uncommitted):读未提交
事务2可以读取到事务1已经操作,未提交的数据
比如
start transaction
delect table stu;
但是我没有提交;
但是其他的事务可以读取到已经删除了,数据用不了了
微信聊天记录的实时性,比如撤回消息,还没有发送了,已经撤回了,速度特别快;
我还没来得及提交---->后台已经知道数据被修改了,这种隔离级别相当于特别低,但是速度特别快;
特点:—并发特别高
但是会出现,脏读,不可重复读,幻读的问题
(2)READCOMMITTED(readcommitted):读已提交
隔离级别提升: 读已经提交的数据
就是你想看到的东西就是我提交准备好的;
事务2只能读取到事务1中已经提交的数据;
但是在读取之前,和读取之后会出现不可重复读的问题和幻读
(3)repeatable read(repeatable 可重复读)–行锁
表示可以重读读取,在事务中解决,数据不一致的问题
但是还是可能出现幻读,数据数目不一致的情况,
mysql5.0—>优化出了一个新可以解决幻读
(4)serializable(串行化):—表锁
最高的隔离级别,直接可以解决幻读的问题;
5.隔离级别使用不当会出现的问题:
(1)脏读:
事务2在读取数据的过程中,已经读取到事务1已经修改,但是未提交的数据,相当于人家没准备好提交,你就已经看到了
很多程度上是假的数据,所以我们判断为脏读;(脏数据)
- 如何避免脏读:
将事务的隔离级别提升,比readuncommitted更高的隔离级别就好了;
也就是隔离级别是 2,3,4;
(2)不可重复读:
‘
事务2,想要读取共享数据, 在事务1修改数据但是未提交的状态下,查询了一次
在事务1数据操作提交之后,再去查询了一次
发现两次的数据有不同之处,然后导致数据读取到的数据是不完整的;
-
如何避免不可重复读:
将事务的隔离级别提升到3,4(repeatable read)可重复读就可以直接解决这个问题
(3)幻读:
在一次事务里面,多次查询之后,结果集的个数不一致的情况叫做幻读。
当事务2,在读取数据时,事务1 增加或者删除一条数据–(数据数量发送变化),但是未提交,所以查到的数据是标准的
事务2提交之后,数据数量发生变化,,感觉是出现幻觉一样;
- 如何避免幻读:
’ 本质上我们直接使用最高的隔离级别(serializable)序列化,可以直接解决幻读的问题
但是mysql在5.0之后优化了,可重复的读的隔离级别,现在可以解决幻读问题
6.mysql的默认隔离级别
- 1.查看当前mysql的隔离级别:
SELECT @@transaction_isolation
select @@tx_isolation mysql 5.0的版本
select @@transaction_isolation; mysql8.0的版本;
show variables like 'transaction_isolation';
mysql默认的隔离级别是:
@@transaction_isolation:
repeateable-read;
这里说一下,MySQL版本还是5.0的话,建议升级一下,当然我也已经准备好了如果升级
如果升级到mysql8.0那些事–嘻嘻
补充说明:
repeateable-read;
可重复读—解决是脏读,不可重复读,以及优化后的幻读的操作;
MySQL的具体的事务变化:
事务隔离级别为读提交时,写数据只会锁住相应的行
事务为串行化(serializable—锁住整张表;)
如果是MySQL 5.0的版本.也可能版本更早一点:查询隔离级别;:
SELECT @@tx_isolation;
具体的结果,要自己查询了,我这边就不过多赘述了;
- 末尾
愿你们都可以在技术的海洋里,乘风破浪,我是卢卡斯,
我们下期再见哦_
要是有比较想看的技术文章和想了解技术栈,可以私信我
品味技术人生,都在摸爬滚打中慢慢变强