Mysql InnoDB 事务与锁

                                                 Mysql InnoDB  事务与锁

  1. 事务
  2. 隔离级别 (并发控制&数据安全)

 MySQL 存储引擎:

  1. MyISAM - 5.0之前默认的 数据库存储引擎, 最为常用,较高的插入,查询速度,不支持事务
  2. InnoDB    事务型数据库的 首选, 支持 ACID事务安全, 支持行级锁定, 5.5版本起 默认的数据库引擎
  3. BDB         源自 Berkeley DB   commit / rollback  支持事务安全

     使用面积最广泛的数据库, MySQL InnoDB

     事务: 指的是 一组逻辑操作单元(insert delete update  select 等等  一个组合的操作单元),

                 是数据从一种状态转变到另一种状态. 如果操作单元中 任何一个 步骤出错 所以数据 回滚到之前的状态

     事务的操作: 定义一个事务, 然后对数据库进行操作(保证数据的一致性

                            commit(成功):永久保存到数据库

                            rollback(失败)  :  回滚到操作之前的数据

 

     事务 transaction : 一系列要发生的操作

     事务安全              :一种保护连续操作是满足实现的一种机制

     事务安全的意义   :保证数据操作的完整性

 

     事务的四个特性 - ACID:

  1. Atomic         原子性 : 保证数据一致性, 数据的操作单元 要么全部成功 要么 全部失败
  2. Consistency 一致性:数据操作单元 中涉及的操作 涉及数据(数据表)要么 全部提交 要么 全部回滚
  3. Isolation       隔离性:事务的操作是相互隔离 不受影响的
  4. Durability     持久性:当操作单元 全部成功执行完毕 数据提交完成,修改的数据将持久保存在数据库中

     InnoDB 默认是行锁:

  • 行锁: 只有当前行被锁定,别的用户不能 操作 (修改)           (查询可以)
  • 表锁: 整个表被锁定   别的用户不能操作表  (修改)               (查询可以)

     MySQL 事务操作分为两种自动事务(默认的) 手动模式

假设有个表是这样的

Mysql InnoDB 事务与锁_第1张图片

----自动提交 commit(默认的)   数据直接保存到数据库
insert into boc_account(name,money) values('james',30000);

----手动事务
start transaction ; ---->告诉存储引擎 以下所有操作(写)不要直接写入到数据库,先存放到事务日志里
update boc_account set money=money-1000 where id=1;
update boc-account set money=money+1000 where id=2;
commit;  ----commit  之前对 数据 的手改只会保存到 事务日志;这个时候其他查询到的数据还是没有修改之前的

    Mysql InnoDB 事务与锁_第2张图片

  • 开启事务
start transaction;
  • 关闭事务
成功:commit;   同步到数据库中 清空事务日志表
失败:rollback; 清空事务日志表

    savepoint 回滚点 ; 设置回滚点

    rollback to  回滚点;

               

  • 查看事务的类型
  • show variables like 'autocommit';
    
    
    ---关闭自动事务
    set autocommit = 0/off;
    
    ---开启自动事务
    set autocommit = 1/on;

 

     两个  操作单元同时更新 一条数据:

----代码1
start transaction;
updata boc_account set momry = 99999 where id = 1;
select * from boc_account;//该查到的结果是  事务日志里面的结果
commit;----//没有执行(没有写)




----代码2
updata boc_account set momry = 9 where id = 1;

----当 代码1 处的 commit; 没有执行完毕的时候 updata 代码会等待 代码1 结束(commit执行完毕)代码2才会 执行

----

 当两个事务同时进行,(同时操作一组数据)------> 锁的机制

锁的机制主要用于管理对共享资源的   并发访问
当多个用户并发的存取数据时, 在数据库中就可能 会产生多个事务同时操作同一行的情况

若对并发操作不加控制就有可能会读取和存储不正确的数据。破坏数据的一致性

  Mysql InnoDB 事务与锁_第3张图片

如图: 如果有上图中的操作序列,那么得到的结果是 120; 当然这个数据是不正确的! 如此就引来的 的概念

 

Mysql InnoDB 事务与锁_第4张图片

 

InnoDB 引擎中的锁

select ... lock in share mode; ---加上一个共享锁


select ... for update;         ---加上一个读取的更新锁


insert update delete;          ---独占锁


gap and  next  key  lock       ---间隙锁  共享锁 + 跟新锁 + 独占锁


------------------------------------------------------------------------------
事务并发控制

     并发引起的常见错误

  1. 第一类丢失更新   update lost;    回滚丢失
  2. 脏度
  3. 幻度
  4. 不严格读取

 

MySQL 四种事务隔离级的说明

  • 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
  • 提交读(Read Committed)       :只能读取到已经提交的数据。Oracle SqlServer等多数数据库默认都是该级别 (不重复读)消除了脏度
  • 可重复读(Repeated Read)     :可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
  • 串行读(Serializable)               :完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

 

===========================================================================================
  隔离级别                                脏读(Dirty Read)          不可重复读(NonRepeatable Read)     幻读(Phantom Read)
===========================================================================================

未提交读(Read uncommitted)        可能                            可能                                                     可能

已提交读(Read committed)          不可能                          可能                                                      可能

可重复读(Repeatable read)          不可能                          不可能                                                  可能

可串行化(Serializable )                 不可能                          不可能                                                  不可能

===========================================================================================

 

----脏度     : 只能在 read-uncommit 隔离级别中发生 可以读到别的 事务 中还未提交(commit)的更  
               新数 据,  极易出错 一般不用

----读已提交 : read-commit
               一个事务只能看到 其他事务已经提交(commit)的更新;消除脏读,是 大多数 数据库的隔
               离级别 Oracle  Sqlerver

----可重复读 :一个事务中进行多次同样的对数据的内容的查询, 得到的结果都是一样的不管位置在哪里。 但         

             不保证对数据条数的查询一致性。 只要存在读改 行数 数据就禁止写  。是 Mysql  InnoDB引     
             擎的默认隔离级别  

 

 

----并发的控制操作
----隔离级别  read-uncommit  脏读流程:


----查看当前连接的 隔离级别
----旧版本 会报错
mysql> select @@session.tx_isolation;
ERROR 1193 (HY000): Unknown system variable 'tx_isolation'

----新版本
mysql> select @@session.transaction_isolation;
+---------------------------------+
| @@session.transaction_isolation |
+---------------------------------+
| REPEATABLE-READ                 |
+---------------------------------+
1 row in set (0.00 sec)





----设置当前数据库连接 隔离级别

set @@session.transaction_isolation = 'read-uncommitted'
insert update delete   语法比较固定, 只是 字段的数目 不一致


insert into 表名(...) values(...);

update 表名 set  ... where id = ...;

delete from 表名 where id = ...;


查询 -- 提高查询的性能








MVCC -多版本并发控制: 读不加任何锁, 读写不冲突。针对于 读操作 多余 写操作的应用。增加了系统的并发性能

 

 

 

你可能感兴趣的:(数据库)