zoukankan      html  css  js  c++  java
  • MySQL_Sql_打怪升级_进阶篇_进阶15: TCL事物控制语言

    进阶15: TCL事物控制语言

    15.1 事物控制语言介绍

    TCL Transaction Control Language 事务控制语言

    事务:一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行。

    案例:转账
    
    张无忌  1000
    赵敏    1000
    
    update 表 set 张三丰的余额=500 where name='张无忌'
    意外
    update 表 set 郭襄的余额=1500 where name='赵敏'
    

    15.2 事务的特性

    ACID

    原子性:Atomicity    	一个事务不可再分割,要么都执行要么都不执行
    一致性:Consistncy  	一个事务执行会使数据从一个一致状态切换到另外一个一致状态
    隔离性:Isolation      	一个事务的执行不受其他事务的干扰
    持久性:Durability    	一个事务一旦提交,则会永久的改变数据库的数据.
    

    15.3 事务的创建

    ①隐式事务:事务没有明显的开启和结束的标记

    比如 insert、update、delete语句
    	delete from 表 where id =1;
    

    ②显式事务:事务具有明显的开启和结束的标记
    前提:必须先设置自动提交功能为禁用

    查看事务默认开启状态 (默认是开启)
    select @@autocommit;
    show variables like '%autocommit%';
    
    set autocommit=0; 
    
    步骤1:开启事务
    set autocommit=0;
    start transaction; 可选的
    
    步骤2:编写事务中的sql语句(select insert update delete)
    语句1;
    语句2;
    ...
    
    步骤3: 结束事务
    commit;  提交事务
    rollback;回滚事务
    
    savepoint 节点名; 设置保存点
    

    15.4 事务的隔离级别

    对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题:

    脏读: 对于两个事务 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段.
    之后, 若 T2 回滚, T1读取的内容就是临时且无效的.

    不可重复读: 对于两个事务T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段.
    之后, T1再次读取同一个字段, 值就不同了.

    幻读: 对于两个事务T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中 插入了一些新的行. 之后, 如果 T1 再次读取同一个表, 就会多出几行.

    事务的隔离性:

    避免并发出现的问题,数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响, 避免各种并发问题,一个事务与其他事务隔离的程度称为隔离级别。数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。

    数据库提供的 4 种事务隔离级别:

    隔离级别 描述
    READ UNCOMMITTED (读未提交) 允许事务读取未被其他事物提交的变更.脏读,不可重复读和幻读的问题都会出现
    READ COMMITED (读已提交数据) 只允许事务读取已经被其它事务提交的变更.可以避免脏读,但不可重复读和幻读问题仍然可能出现
    REPEATABLE READ (可重复读) 确保事务可以多次从一个字段中读取相同的值.在这个事务持续期间,禁止其他事物对这个字段进行更新.可以避免脏读和不可重复读,但幻读的问题仍然存在.
    SERIALIZABLE (串行化) 确保事务可以从一个表中读取相同的行.在这个事务持续期间,防止其他事务对该表执行插入,更新和删除操作.所有并发问题都可以避免,但性能十分低下.

    Oracle 支持的 2 种事务隔离级别:READ COMMITED,SERIALIZABLE。 默认的事务隔离级别为: READ COMMITED

    Mysql 支持的 4 种事务隔离级别。默认的事务隔离级别为: REPEATABLE READ

    隔离级别/并发问题 脏读 不可重复读 幻读
    read uncommitted 会出现 会出现 会出现
    read committed 不出现 会出现 会出现
    repeatable read 不出现 不出现 会出现
    serializable 不出现 不出现 不出现

    查看隔离级别 select @@transaction_isolation;

    mysql> select @@transaction_isolation;
    +-------------------------+
    | @@transaction_isolation |
    +-------------------------+
    | REPEATABLE-READ         |
    +-------------------------+
    1 row in set (0.00 sec)
    

    设置隔离级别
    set session|global transaction_isolation= 隔离级别;

    #例如:设置成读未提交
    set global transaction_isolation='read-uncomminted'; 
    
    read uncommitted
    read commited
    repeatable read
    serializable
    

    15.5 事务的演示

    0.创建相关测试环境

    SHOW VARIABLES LIKE 'autocommit';
    SHOW ENGINES;
    
    DROP TABLE IF EXISTS account;
    CREATE TABLE account(
    	id INT PRIMARY KEY AUTO_INCREMENT,
        username VARCHAR(20),
    	balance DOUBLE
    );
    
    INSERT INTO account (username,balance)VALUES(”张无忌,1000),('赵敏',1000);
    

    1.演示事务的使用步骤

    ①开启事务
    SET autocommit=0;
    START TRANSACTION;
    
    ②编写一组事务的语句
    UPDATE account SET balance = 1000 WHERE username='张无忌';
    UPDATE account SET balance = 1000 WHERE username='赵敏';
    
    ③结束事务
    #ROLLBACK;
    COMMIT;
    
    SELECT * FROM account;
    

    2.演示事务对于delete和truncate的处理的区别

    #delete 删除可以回滚
    SET autocommit=0;
    START TRANSACTION;
    
    DELETE FROM account;
    ROLLBACK;
    
    #truncate 删除无法回滚
    SET autocommit=0;
    START TRANSACTION;
    
    DELETE FROM account;
    ROLLBACK;
    

    3.演示save point 的使用

    SET autocommit=0;
    START TRANSACTION;
    DELETE FROM account WHERE id=25;
    SAVEPOINT a;        #设置保存点
    DELETE FROM account WHERE id=28;
    ROLLBACK TO a;      #回滚到保存点
    
    SELECT * FROM account;
    

    4.演示事务的脏读,不可重复读,幻读

    操作示例.演示(1,2,3)这几种级别:
    1.RU Read-uncommitted
    调整参数:
    set global transaction_isolation='read-uncomminted';
    
    ①脏读的例子.
    sessinon1:
    begin;
    updata city set name='oldli' where id=2;
    
    sessinon2:
    begin;
    select * from city;
    
    说明:
    一句话: 读到未提交的脏页.
    比如说,有两个会话,会话A和会话B,当会话A开启事务begin时,执行一条DML语句update一条数据,并未完成commint,此时的会话B,也开启一个事务begin后,执行的一条语句是select, 发现的问题是 能看到刚刚会话A执行的update的内容,这是不允许的, 这种情况称为"脏读"  
    应用场景:
    脏读生产中是不可以出现的.
    
    ②不可重复读数据
    sessinon1:
    begin;
    updata city set name='oldli' where id=2;
    commit;
    
    sessinon2:
    begin;
    select * from city;
    commint;
    
    说明:
    一句话: 在同一事务内,做同一样的操作,不同时间段得到的结果是不一致的情况,称为不可重复读.
    比如说,有两个会话,会话A和会话B,当会话A开启多个事务begin时,多次执行一条不同DML语句update数据,并完成commint,此时的会话B,执行select的时候,会发现每次查询的结果,都不一致,这种情况称为"不可重复读" 
    应用场景:
    对于事务的隔离性,数据最终一致性要求比较高的业务是不允许出现的. 如果能容忍的话 可以调整RC模式.
    
    ③幻读
    sessinon1:
    准备环境:
    create table test (id int, num int, name varchar(20));
    insert into test values(1,10,'oldli'),(2,20,'lizicheng'),(3,30,'weichunxue');
    
    事务正在做批量更新
    begin;
    update test set num=100 where num>10;
    commit; 
    select * from test;
    
    sessinon2:
    事务插入一条数据
    begin;
    insert into test values(40,333,'aaa'); 
    commit;
    select * from test;
    说明:
    一句话: 更新insert数据的时候,出现换行的数据.
    比如说,有两个会话,会话A和会话B,当会话A开启事务begin时,执行批量的DML语句update数据,完成commint,此时的会话B,执行insert的时候,也完成commint,当会话A和会话B执行select的时候,会发现会话A多出一行(换行)的数据,(这个数据是会话B insert事务进来的)并不是最终想要的结果,这种情况称为"幻读"
    
    小结:
    不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
    脏读: 	     update 事务未提交,读到脏页数据
    不可重复读:    update 事务提交,一定时间段内的数据不一致
    幻读:         insert 事务提交,数据会多出一行.
    
  • 相关阅读:
    arcgis10.2转shp文件中文乱码问题解决方案
    Android Context作为参数传递this
    andriod inputbox
    andriod inputType
    《ArcGIS Runtime SDK for Android开发笔记》——(5)、基于Android Studio构建ArcGIS Android开发环境(离线部署)(转)
    终于理解了什么是LGPL
    产品经理如何与强势的技术沟通? 技术比较有资历,会以技术无法实现等方面的原因拒绝处理产品提出的需求。 你们是否遇到这样的技术? 产品懂技术的话,是不是会好一些,因为可以和技术说“行话”了,并且产品懂技术就不会被忽悠了。
    Core Dump总结
    LIBRARY_PATH是编译时候用的,LD_LIBRARY_PATH是程序运行是使用的
    如何禁止C++默认成员函数
  • 原文地址:https://www.cnblogs.com/liych/p/13929569.html
Copyright © 2011-2022 走看看