MySQL 视图与事务

视图

  • sql 语句很复杂,又要在很多地方写,改的时候太麻烦了,这时候可以用视图解决

  • 视图可以隐藏表的字段名。

根据视图来查的,所以如果起了别名别名就是那个试图的字段名

只能将select语句创建为视图

对视图增删改(DML:insert delete update)会影响到原表数据。

在这里插入图片描述



创建视图

create [or replace] view v_emp as select e.ename,d.dname from emp e join dept d on e.deptno = d.deptno;

修改视图

alter view v_emp as select e.ename,d.dname,d.deptno from emp e join dept d on e.deptno = d.deptno;

删除视图

drop view if exists v_emp;



事务

事物就是一个最小的工作单元,在数据库中,事物表示一件完整的事

例如:一个业务的完成可能需要多条DML语句共同配合才能完成,例如转账业务,需要执行两条DML语句,先更新张三账户的余额,再更新李四账户的余额,为了保证转账业务不出现问题,就必须保证要么同时成功,要么同时失败,怎么保证同时成功或者同时失败呢?就需要使用事务机制。

事务只针对DML语句有效:因为只有这三个语句是改变表中数据的。

  1. insert
  2. delete
  3. update


事物的四大特性(ACID)

  • 原子性(Atomicity):是指事务包含的所有操作要么全部成功,要么同时失败。

  • 一致性(Consistency):是指事务开始前,和事务完成后,数据应该是一致的。例如张三和李四的钱加起来是5000,中间不管进行过多少次的转账操作(update),总量5000是不会变的。这就是事务的一致性。

  • 隔离性(Isolation):隔离性是当多个⽤户并发访问数据库时,⽐如操作同⼀张表时,数据库为每⼀个⽤户开启的事务,不能被其他事务的操作所⼲扰,多个并发事务之间要相互隔离。

  • 持久性(Durability):一旦事务成功提交,其对数据库数据的更改将被永久保存下来,不会因为系统故障、断电等问题而丢失这些更改


事务的开启和结束

MySQL 事物如果不执行:strat[begin] trancaction ,就一条语句提交一次事物。我们实际的业务是一堆 DML 构成事物,所以需要手动开启事物

回滚:rollback

提交:commit;

只要手动开启事物:执行回滚或者提交就是一次结束操作。所以要想好再提交,提交之后就回滚不了了



事物隔离级别

在这里插入图片描述

  • 隔离级别从低到高:读未提交 < 读提交 < 读可重复读 < 串行化

  • 现象的严重程度从低到高:幻读 < 不可重复读 < 脏读

mysql数据库默认是 读提交。Oracle 默认是 可重复读

存在脏读的话,就一定存在不可重复读和幻读问题。



现象

脏读

一个事务读取了,另一个事务未提交的数据。就是读取到了另一个事务中的脏数据。在这种情况下,如果事物回滚或者修改了这些数据,那么读取这些脏数据的事务所处理的数据就是不准确的。


不可重复度

一个事务内,多次读取同一个数据行。得到的结果可能不一样。这是由于其他事务对数据进行了修改操作。导致数据的不一致性


幻读

事务执行过程中,前后两次相同的查询条件得到的结果不一,可能会变多或变少



隔离级别

读未提交(READ UNCOMMITTED)

A事务与B事务,A事务可以读取到B事务未提交的数据。这是最低的隔离级别。几乎两个事务之间没有隔离。这种隔离级别是一种理论层面的,在实际的数据库产品中,没有从这个级别起步的。


读提交 (READ COMMITTED)

A事务与B事务,A事务可以读取到B事务提交之后的数据。Oracle数据库默认的就是这种隔离级别。


可重复读 (REPECTABLE READ)

A事务和B事务,A事务开启后,读取了某一条记录,然后B事务对这条记录进行修改并提交,A事务读取到的还是修改前的数据。这种隔离级别称为可重复读。MySQL数据库默认就是这种隔离级别。


串行化 (SERIALIZABLE)

这种隔离级别最高,避免了所有的问题,缺点是效率低,因为这种隔离级别会导致事务排队处理,不支持并发。



查看与设置事务隔离级别

查看当前事务隔离级别

select @@transaction_isolation -查看当前会话隔离级别
select @@gobal.transaction_isolation -查看全局的隔离级别

设置事务隔离级别

会话级:set session transaction isolation level 事务隔离级别
全局级:set global transaction isolation level 事务隔离级别

事务隔离级别:
1.read uncommitted
2.read committed
3.repeatable read
4.serializable


重复读的幻读问题

可重复读,能很大程度上避免了幻读问题,但是并不能完全解决。



快照读解决幻读

普通的 select 语句都是采用快照读。(类似就是把那个时间段的表数据,保留下来。)

原理:

​ 由 MVCC(多版本并发控制) 实现,实现的方式是开始事务后会创建一个 Read View 对象,后续查询语句利用整个 Read View,通过这个 Read View 就可以在 undo log 版本链找到快照查询执行时候的那个版本的数据。所以事务过程中每次快照查询数据都是一样的,即使中途有其他事务插入了新记录,是查询不出来这条数据的。避免了幻读


当前读解决幻读

当前读包括:update、delete、insert、select…for update。就是 DML 加上 for update。单独执行 DML 语句也会隐式执行当前读

原理:

select…for update加的锁叫做:next-key lock。我们可以称其为:间隙锁 + 记录锁。间隙锁用来保证在锁定的范围内不允许insert操作。记录锁用来保证在锁定的范围内不允许delete和update操作。提交后锁失效



出现幻读的两种情况

在同一个事务处理过程中,如果前后两次都采用快照读,或者都采用当前读,则不会出现幻读问题。如果第一次使用快照读,后面使用了当前读,则会出现幻读问题。



第一种产生幻读的场景

A事务与B事务。在A事务中第一次查询使用快照读,B事务插入数据。然后在A事务中第二次查询使用当前读。则会产生幻读现象。


第二种产生幻读的场景

事务A与事务B,在事务A中第一次查询使用快照读,在事务B中插入一条数据,然后在事务A中更新事务B插入的那条记录,最后在事务A中再次使用快照读。则会发生幻读现象。



幻读总结

MySQL 可重复读隔离级别并没有彻底解决幻读,只是很大程度上避免了幻读现象的发生。
要避免这类特殊场景下发生幻读的现象的话,就是尽量在开启事务之后,马上执行 select … for update 这类当前读的语句,因为它会对记录加 next-key lock,把数据锁住。从而避免其他事务插入一条新记录。

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值