MySQL——什么是事务?四大特性ACID?隔离级别?

什么是事务(ACID)?事务的作用是什么?

MySQL中,事务其实是一个最小的不可分割的工作单元,事务能够保证一个业务的完整性。

UPDATE user SET money=money-100 where name = 'a';

UPDATE user SET  money=money+100 where name ='b';

多条SQL语句,可能会有同时成功的要求,要么就同时失败

如何控制事务?

MySQL默认开启事务(自动提交) SELECT @@autocommit;

默认事务开启的作用是什么?

当我们执行一条SQL语句,效果会立即体现出来,且不会回滚。

回滚:撤销SQL语句执行效果       rollback;

设置MySQL自动提交为false         SET autocommit=0;

关闭了MySQL的自动提交(commit) 需要自己手动提交    commit;

commit后再撤销(rollback)是无法撤销成功的(事务的持久性)

事务的四大特征?

A 原子性(atomicity):事务是最小的单位,不可再分割

C 一致性(consistency):事务要求,同一事务中的SQL语句,必须保证同时成功或者同时失败

I 隔离性(isolation):事务1和事务2之间是有隔离性的

D 持久性(durability):事务一旦结束(commit),就不可以返回(rollback)

小结

事务开启:1. 修改默认提交   SET autocommit=0;

                  2.  BEGIN;

                  3. START TRANSACTION;

事务手动提交: commit;

事务手动回滚: rollback;

事务的隔离性?

1. read uncomitted; 读未提交的(脏读)

如果事务a和事务b,a 事务对数据进行 操作,在操作过程中,事务未被提交,但b可以看到a操作的结果

insert into user values(2,'b',1000);

insert into user values(3,'c',1000);

insert into user values(4,'d',1000);

如何查看数据库的隔离级别?

mysql 8.0   select @@global.transaction_isolation; (系统级别)

                   select @@transaction_isolation;           (会话级别)


mysql5.x   select @@global.tx_isolation;   (系统级别)

                  select @@tx_isolation;             (会话级别)

如何修改系统隔离级别?

set global transaction isolation level read uncommitted;

什么是脏读?

脏读:一个事务读到了另外一个事务未提交的数据

如果在两个不同的地方,都在进行操作,如果事务a开启之后,他的数据可以被其他事务读取到,

这样就会出现脏读。实际开发中,不允许脏读出现

例如:a 给 c 转账800块

2. read committed; 读已经提交的(不可重复读——针对多个事务对同一字段的修改)

一个事务的提交,导致另外一个事务已更新的数据丢失,或者两次读取结果不一致。

3. repeatable read; 可以重复读(MySQL默认级别)

什么是幻读?

事务a和事务b同时操作一张表,事务a提交的数据也没有被事务b读到,就会造成幻读(对于一个表查询到的行数不一致)(比如:明明a插入了一条数据,b同样也插入这条数据,插入前进行查询发现表中无记录,但插入会报错,说该数据已存在)

4. serializable; 串行化(可以解决幻读)

语句被卡住了,当表被另外一个事务操作时,其他事务的写操作是不可以进行的

进入排队状态(串行化),直到其他事务事务结束,这个事务的写入操作才会执行

在没有等待超时的情况下

串行化的问题是:性能很差

如何实现read repeatable?

MySQL是通过MVCC机制来实现的,即:多版本并发控制,multi-version concurrency control。

使用innodb存储引擎,会在每行数据后添加两个隐藏列,一个保存行创建时间的事务id,另一个保存删除时间的事务id,事务id由MySQL自己创建并且全局唯一递增的。

创建事务id<=当前事务id && 当前事务<删除事务id  就能查到这一行

在一个事务内查询的时候,mysql只会查询创建时间的事务id小于等于当前事务id的行,这样可以确保这个行是在当前事务中创建,或者是之前创建的;

同时一个行的删除时间的事务id要么没有定义(就是没删除),要么是比当前事务id大(在事务开启之后才被删除);满足这两个条件的数据都会被查出来。

如果在某个事务执行期间,别的事务更新了一条数据,其实就是在innodb中插入了一行记录,并把创建时间设置为新的事务id,同时将这条记录之前的那个版本的删除时间设置为新的事务的id。

这样的话,事务其实对某行记录的查询,始终都是查找之前的那个快照,因为之前的那个快照的创建时间小于等于自己事务id,然后删除时间的事务id比自己事务id大,所以这个事务运行期间,会一直读取到这条数据的同一个版本。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值