三 . Mysql事务隔离级别
事务执行的语句:
select 不需要事务的
插入,更新,删除 默认情况下一条sql就是一个事务,事务默认是开启自动提交的
# sql语句的执行 (SET AUTOCOMMIT=0), 把自动提交给取消
开始事务 begin
执行sql (如果中间错误了,执行rollback)
提交事务 commit
# 存档(savepoint)
# mysql的隔离级别
#查看mysql 默认的隔离级别
@@global.transaction_isolation 系统的隔离级别
@@transaction_isolation 当前会话的隔离级别
select @@global.transaction_isolation,@@transaction_isolation;
# 隔离级别
need-to-insert-img
- 读未提交(Read uncommitted):在该隔离级别下,所有的事务都会读取到其他事物没有commit的结果,读取未提交的事务也成为脏读。
- 读已提交(Read committed):该隔离级别解决的脏读的并发问题,因为事务读取的数据都是其它事务已经提交的事务,不会发生回滚了。但是没有解决不可重复读和幻读的问题,因为在一个事务的多次读操作之间,可能存在修改和新增的操作。
- 可重复读 (Repeatable read):该隔离级别解决了不可重复读的并发问题,保证一个事务的多次读取之间读取到的是同一份数据。
- 可串行化(Serializable):提供严格的事务隔离级别,要求事务去序列化执行,不能并发执行。
总之,事务的隔离级别越高越能保证事务的完整性和统一性,但并发性能就越差。
三个情况造成死锁:
1.脏读:事务A读取了事务B更新的数据,事务B回滚,事务A之前读到的数据就是脏数据
2.不可重复读:事务A多次读取同一个数据,在这期间,事务B修改了该数据,导致事务A多次读取的数据不一致。
3.幻读:事务A将某张表中的某个字段的所有数据设为空,在这时,事务B新增了一条数据,事务A操作结束后,发现有一条数据的该字段没有被设置为空,好像产生幻觉一样。
总结:不可重复读侧重于修改,幻读侧重于新增和删除。解决不可重复读需要锁住满足条件的行,解决幻读需要锁住整张表。
read uncommitted (读未提交) --> 导致脏读,读取到其他事务没有提交的数据,如果其他万一回滚,这是数据无效。
REPEATABLE-READ(默认的隔离级别,读已提交) ->
解决脏读,导致不可重复读取,在同一事务中前后两次查询的数量可能不一致。
repeatable-read (可重复读) ->
解决不可重复读,导致幻读
1. 在A中开启事务 2. 在B中开启事务
3. 查询一下叫'李四'学生 4. 插入‘李四’的学生
5. 提交事务
6. 查询‘李四’,李四不存在
7 插入一下李四,有插入不成功(name要唯一)
serializable(串行化)
解决幻读
1. 一个事务一个的执行,事务都不并发,没有任何问题,但是会到性能下降
# 隔离界别越高,性能越下降(采用默认的隔离级别就可以了)
# 修改隔离级别
set session transaction isolation level read uncommitted
set session transaction isolation level read committed
set session transaction isolation level repeatable read
# 视图
View
应用场景
1. 数据关联很复杂
2. 有一些数据不能想某些人看 (让别人通过视图查询数据)
什么是视图
一张虚拟表,有字段等,但是不真正的存储数据,对查询结果的一个引用,在使用视图的时候,我们以查询为主,基本不上不做更新,添加,删除操作。
1. 查询 张三的人,他的各门课程成绩, 按照降序进行排序
select st.s_name sname, cu.c_name cname, sc.s_score score from student st left join score sc on st.s_id = sc.s_id left join course cu on cu.c_id = sc.c_id where st.s_name = '钱电' order by score desc;
# 可以使用视图
1. create view temp as select st.s_id sid,st.s_name sname, cu.c_name cname, sc.s_score score from student st left join score sc on st.s_id = sc.s_id left join course cu on cu.c_id = sc.c_id
2. select * from temp where sname = '赵雷' order by score desc;
# 注意: 如果希望更新视图,视图和数据表的关系一一对应的,如果希望做更新和插入,直接在原表上进行
# 视图不属于这一次会话, 一次创建之后可以一直使用
# 视图是对真实数据表的引用,当真实数据表发生变化的时候,视图的数据也跟着发生变化。