zoukankan      html  css  js  c++  java
  • mysql基础之-mysql锁和事务(七)

    0x01

    MySQL锁:
    执行操作时施加锁的模式
    读锁:用户在读的时候施加的锁,为防止别人修改,但是用户可以读,还被称为共享锁 不会对其他用户进行阻塞

    理解: ----->(这里的不阻塞,是可以让用户读(即-不对用户读进行阻塞),但是不能让用户写入数据,是会阻塞写入的数据,除非解锁)

    显示锁(表级锁):
    lock tables:施加锁
      LOCK TABLES
      tbl_name lock_type
      [, tbl_name lock_type] ...
    锁的类型
      READ | WRITE
      unlock tables:解锁

    实例:

    原表中数据,如下:

    对表进行读锁,用其他用户进行查询表内容依然可以进行查询,如下

    但是此时若要对表进行写入数据的操作那么 会被阻塞,如下:

    若要不被阻塞,那么就要解锁,如下:


    写锁:独占锁,排它锁。其他用户不能读,不能写 会对其他用户进行阻塞,只有阻塞解除了,其他用户才能读 (阻塞的)

    实例:

    对表进行写锁

    对表进行解锁便能查询


      锁粒度:
        表锁:table lock
        锁定了整张表
      行锁:row lock
        锁定了需要的行

        粒度越小,开销越大,但并发性越好:
        粒度越大,开销越小,但并非性越差;

      锁的实现位置:
        MySQL锁:可以手动使用,可以使用显示锁
        存储引擎锁:自动进行的(隐式锁),

    0x02

      InnoDB存储引擎也支持另外一种显示锁(锁定挑选出的部分行,行级锁
        select .... lock in share mode
        select .... for update

    实例:

      首先这种行级锁是适用于innodb存储引擎

      若不是innodb存储引擎,则需要更改,当然,大的实际的生产环境数据很庞大的环境,是不建议更改随便更改存储引擎,我这是测试,所有更改为innodb存储引擎

     alter table classes engine 'innodb';

    如下所示已经更改为innodb存储引擎

    show table status like 'classes'G;

    设置行级锁模式

    select * from classes where classid <= 5 lock in share mode;

    PS:在以上行级锁,只能在sql语句执行的时候实现锁的机制,sql语句执行完毕,便不再起作用,所有这里无法演示其效果

    0x03

    事务:Transaction
      事务就是一组原子性的查询语句,也即将多个查询当作一个独立的工作单元。 

        理解事务:就是将一系列的sql语句当作“一句”来执行的一种机制——该系列语句要么全部执行成功,要么一个都不执行。

        事务实际应用:我们经验中的一个“操作”,其实常常对应着数据库(表)的2个或2个以上的操作,此时就应该让此2个操作具有“整体性”。比如网银汇款,其实是将一个储户中的钱减少一个数目,再将另一个储户的钱增加一个数目。如果只做完了前者,后者因为某种原因没有做完就出错了,此时就悲剧了。

      ACID测试:能够满足ACID测试就表示其支持事务,或兼容事务
        A:Atomicity,原子性,一个事务必须被分为不可分割的单元,要么都执行要么都不执行都执行
        C:Consistency,一致性,从一个一致性状态转到另外一个一致性状态,而不会导致数据丢失
        I:Isolaction,隔离性。一个事务的所有修改操作在提交前对其他事务时不可见的
        D: Durability, 持久性,一旦事务得到提交,其所做的修改会永久有效

    启动事务
      start transaction;

    事务提交
      commit

    实例:

    开启事务,删除数据。

    上述删除数据,但是没有提交,commit,可以通过回滚,进行恢复,如下:


    事务回滚
      rollback

    如若按照上述进行删除数据,但是进行提交,commit,那么数据就真的被删除了,不能再回滚


    SAVEPOINT 控制回滚的位置
      SAVEPOINT identifier
      ROLLBACK [WORK] TO [SAVEPOINT] identifier

    实例:

    再设置一个回滚点,如下:

    尝试回滚对应回滚的位置:

    0x04

    如何没有显式启动事务,每个语句都会当作一个默认的事务,其执行完成会被自动提交  ---mysql的默认功能

    show global variables like '%commit%';      ------ 为 ‘ON’ 表示自动提交

    select @@global.autocommit          ---- 为 数字 ‘1’ 表示自动提交

    关闭其自动提交功能   --- 设置为 ‘0’  --如下
    set global autocommit = 0

    注意 关闭自动提交,请记得手动启动事务,应记得手动提交

    安全性越高,并发性越低

    隔离级别:
      READ UNCOMMITTEND(读未提交),不可重复读,幻读  ---- 脏读 -> 能够读取别人尚未提交的数据叫脏读 -- 用户没有提交数据,但是别的用户能查询看到数据-读未提交
      READ COMMITTEND(读提交)  用户没有提交数据,查询看不到数据--- 读提交
      REPEATABLE READ (可重读)   ---mysql默认的隔离级别
      SERIALIZABLE(可串行化)强制事务的串行执行避免了幻读;性能极低

    所有事务只支持innodb存储引擎

    查看mysql的事务隔离级别
      show global variables like '%iso%'
      select @@global.tx_isolation

    实例:

    更改事务隔离级别为读未提交

    set global tx_isolation='read-uncommitted';

    上述设置完成之后,因为是全局环境,所有要重新登录mysql进行测试,

    回滚之后,发现查询脏读的数据,是一样的,此时验证了不可重复读。

    实例:

    更改事务隔离级别为读提交

    set global tx_isolation='read-committed';

    开启事务,进行删除数据测试

    此时在没有提交的情况下,在另一个会话中开启事务

    start transaction;

    进行查询,如下:

    此时在提交的情况下,在另一个会话中查看数据,如下:

    上述没有脏读。

    实例:

    更改事务隔离级别为REPEATABLE READ (可重读):

    set global tx_isolation='repeatable-read';

    开启事务,进行删除数据测试

    此时在没有提交的情况下,在另一个会话中开启事务

    start transaction;

    进行查询,如下:

    发现没有读到被删除后的数据,没有脏读。

    当提交之后,发现还是看不到被删除的数据

    上述是进行删除操作的用户,做了commit操作,她自己能够查看删除后的数据,但是其他用户并没有看到被删除后的数据,此时,其他用户需要自己commit才能查看被删除的数据,如下:

    这就是REPEATABLE READ     可重读性

    实例:

    更改事务隔离级别为SERIALIZABLE(可串行化)强制事务的串行执行避免了幻读;性能极低

    set global tx_isolation='serializable';

    分别开启两个会话重新登录mysql开启事务,其中一个用户做删除操作,发现无法操作,一直卡着。

    但是,如果两个用户都删除操作,会有其中一个用户操作成功,如下:

    SERIALIZABLE(可串行化)强制事务的串行执行避免了幻读;性能极低

    建议:对事物要求不特别严格的场景下,可以使用读提交

    MVCC:多版本并发控制
    每个事务启动时,InnoDB会为每个启动的事务提供一个当下时刻的快照
    为实现此功能,InnoDB会为每个表提供两隐藏的字段,一个用于保存行的创建时间,一个用于保存行的失效时间
    里面存储的系统版本号

    旨在两个隔离级别下有效:read committed和repeatable read

  • 相关阅读:
    夺命雷公狗---微信开发22----微信客户端下载多媒体文件
    夺命雷公狗---微信开发21----通过程序进行下载多媒体文件
    夺命雷公狗---微信开发20----编写程序进行上传多媒体文件
    夺命雷公狗---微信开发19----使用网页调试工具调试该接口进行文件的上传与下载
    夺命雷公狗---微信开发18----删除自定义菜单
    夺命雷公狗---微信开发17----自定义菜单的事件推送,响应菜单的CLICK
    夺命雷公狗---微信开发16----自定义菜单的查询
    夺命雷公狗---微信开发15----编写进行创建自定义菜单
    夺命雷公狗---微信开发14----用网页调试工具调试自定义菜单接口
    夺命雷公狗---微信开发13----获取access_token
  • 原文地址:https://www.cnblogs.com/autopwn/p/5097036.html
Copyright © 2011-2022 走看看