SQL事务隔离

事务分类:    

1 显式事务:用begin transaction明确指定事务的开始。
2 隐性事务:打开隐性事务:set implicit_transactions on,当以隐性事务模式操作时,SQL Servler将在提交或回滚事务后自动启动新事务。无法描述事务的开始,只需要提交或回滚事务。
3 自动提交事务:SQL Server的默认模式,它将每条单独的T-SQL语句视为一个事务。如果成功执行,则自动提交,否则回滚。  

并发事务成败皆归于锁——锁定  

 在多用户都用事务同时访问同一个数据资源的情况下,就会造成以下几种数据错误:

  • 更新丢失:多个事务同时对一个数据资源进行更新,必定会产生被覆盖的数据,造成数据读写异常。
  • 不可重复读:在一个事务中多次读取一条数据,而另外一个事务则同时更新了这条数据,造成第一个事务多次读取数据不一致。
  •  脏读:事务已经更新数据,另一个事务此时读取同一份数据,由于一些原因,前一个事务回滚,造成后一个事务读取的数据不一致。
  • 幻读:第一个事务读取一个结果集后,第二个事务,对这个结果集经行增删操作,然而第一个事务中再次对这个结果集进行查询时,数据发现丢失或新增。

    然而锁定,就是为解决这些问题所生的,他的存在使得一个事务对他自己的数据块进行操作的时候,而另外一个事务则不能插足这些数据块。这就是所谓的锁定。

常见解决死锁方法:

  • 不同程序并发存取多个表,约定相同顺序访问表
  • 同一个事务,一次锁定所需所有资源
  • 业务部分,升级锁粒度,使用表级锁定


1、锁定从类别可以分为2种:

  • 共享锁(S):还可以叫他读锁。可以并发读取数据,但不能修改数据。也就是说当数据资源上存在共享锁的时候,所有的事务都不能对这个资源进行修改,直到数据读取完成,共享锁释放。共享锁可以同时加上多个。
  • 排它锁(X):还可以叫他独占锁、写锁。就是如果你对数据资源进行增删改操作时,不允许其它任何事务操作这块资源,直到排它锁被释放,防止同时对同一资源进行多重操作。排它锁只能加一个,它和其他排它锁和共享锁相斥。

2、锁从粒度可以分为3种(InnoDB):

  • 行级锁
    • select * from tab_with_index where id = 1 for update; for update行级锁定,前提id是有索引的列,如果id没有索引,这是表索引
    • InnoDB默认
    • 分为共享锁和排它锁
    • 出现死锁,并发度高
  • 表级锁 
    • MyISAM,InnoDB支持
    • 分为共享锁和排它锁
    • 不出现死锁,并发度低
  • 页级锁
    • 介于表级与行级
    • 出现死锁,并发度一般  

3、锁算法(InnoDB):

  1. Record:单行记录上的锁
  2. Gap:间隙锁,锁定一个范围,但是不包含记录本身
  3. Next-key:record+gap锁定一个范围,包含记录本身

使用场景:

  • 行查询使用next-key
  • next-locking keying解决幻读问题
  • 查询索引唯一,将next-key降为record
  • gap阻止多个事务将记录插入同一个范围,防止幻读
  • 除外键和唯一性,其他情况使用record
  • 显示关闭gap:将事务隔离设置read committed;将InnoDB_locks_unsafe_for_binlog设置为1

事务隔离级别:

  • read uncommitted(读取未提交):出现脏读,不可重复读,幻读
  • read committed(读取并提交):出现不可重复读,幻读,SqlServer,Oracle默认级别
  • read repeatable(可重复读):出现幻读,MySQL默认级别
  • read serializable(可串行化):InnoDB在分布式事务
原文地址:https://www.cnblogs.com/ivy-xu/p/5716275.html