事务一:数据库基础知识

  • 一:事务概述
数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。
一个数据库事务通常包含了一个序列的对数据库的读/写操作。它的存在包含有以下两个目的:
      1) 为数据库操作序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
      2)当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。

事务的四个特性:ACID

1.原子性 aotmic 

 事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。

2.一致性 consistent

事务在完成时,必须使所有的数据都保持一致状态。

3.隔离性 isolaton

由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时数据所处的状 态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据

4.持久性 duration

事务完成后,它对系统的影响是永久性的
  • 二:隔离级别

1.隔离级别概述

事务隔离定义了数据库系统中一个操作产生的影响什么时候以哪种方式可以对其他并发操作可见。

即:主要影响的是并发事务之间的可见性

扫描二维码关注公众号,回复: 536676 查看本文章

   (1)未提交读Read Uncommitted

    最低级别的隔离级别:意思就是即使一个更新语句没有提交,但是别的事务可以读到这个改变.这是很不安全的,可能会出现脏读。

    (2)读提交 Read Committed

    语句提交以后即执行了COMMIT以后别的事务就能读到这个改变. 可能会出现不可重复读

    (3)可重复读 Repeatable Read

     在同一个事务里面先后执行同一个查询语句的时候,得到的结果是一样的.可能会出现幻读。
   (4)序列化 Serializable
   在这个级别下,所有的事务的完整性都被保留,意味着所有的事务都可以被序列化的执行,只有当两个事务之间没有任务冲突时,才能并发的执行。
 

2.隔离级别修改SQL

     (1) 查询mysql数据库系统级别的事务隔离级别

select @@global.tx_isolation

   (2)InnoDB会话级别的事务隔离级别

 SELECT @@tx_isolation

(3)修改数据库事务隔离级别

SQL SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE} 
  • 三.隔离级别VS读现象(Read phenomena)

举例说明

在表user 中有下列数据

mysql> select * from user;
+----+----------+------+
| id | username | age  |
+----+----------+------+
|  1 | juzy     |   20 |
+----+----------+------+

1.脏读  dirty reads 

当一个事务允许读取另外一个事务修改但未提交的数据时,就可能发生脏读(dirty reads)。

如下实例:事务1隔离级别设置为read uncommitted,事务2正在修改id=1的数据还没有提交,事务1读取到了这一数据。如果事务2回滚,那么事务1就获取到了脏数据

事务1

事务2
mysql> set session transaction isolation level read uncommitted;
 
 
mysql> start transaction;
mysql> update user set age=30 where id=1;
 
mysql> select * from user where id =1;
+----+----------+------+
| id | username | age  |
+----+----------+------+
|  1 | juzy     |   30 |
+----+----------+------+
 
 

2.不可重复读(non-repeatable reads)

在一次事务中,当一行数据获取两遍得到不同的结果表示发生了“不可重复读(non-repeatable read)”.

未提交读和提交读都有可能发生不可重复读现象。

事务1 事务2
mysql> select * from user where id =1;
+----+----------+------+
| id | username | age  |
+----+----------+------+
|  1 | juzy     |   20 |
+----+----------+------+
 
 
 
mysql> update user set age=30 where id=1;
 
mysql> select * from user where id =1;
+----+----------+------+
| id | username | age  |
+----+----------+------+
|  1 | juzy     |   30 |
+----+----------+------+
 
 

3.幻读 (phantorm read )

 在事务执行过程中,当两个完全相同的查询语句执行得到不同的结果集。这种现象称为“幻影读(phantom read)”

事务1 事务2
mysql> select * from user where age>=20;
+----+----------+------+
| id | username | age  |
+----+----------+------+
|  1 | juzy     |   20 |
+----+----------+------+
 
 
 
mysql> insert into user(id,username,age)values(2,'yolanda',30);
 
mysql> select * from user where age>=20;
+----+----------+------+
| id | username | age  |
+----+----------+------+
|  1 | juzy     |   20 |
|  2 | yolanda  |   30 |
+----+----------+------+
 
 

各个隔离级别可能会出现的读现象 

离级别        脏读(Dirty Read)         不可重复读(NonRepeateable Read)  幻读(Phantom Read)
未提交读(Read uncommitted) 可能 可能 可能
已提交读(Read committed) 不可能 可能 可能
可重复读(Repeatable read) 不可能 不可能 可能
可序列化(Serializable) 不可能 不可能 不可能

不可重复读和幻读的区别

很多人容易搞混不可重复读和幻读,确实这两者有些相似。但不可重复读重点在于update和delete,而幻读的重点在于insert。

  • 四.默认的隔离级别

目前mysql的默认隔离级别是RR,oracle的默认隔离级别是RC

且mysql的RR 级别下不会出现幻读。see http://www.ningoo.net/html/2008/mysql_innodb_transaction_isolation_level.html

  • 五:隔离级别VS锁

在传统的数据库系统的实现中,一般实现不同等级的隔离性方法是使用锁定(lock)

1.锁

乐观锁(optimistic locking):乐观锁相信数据之间的数据竞争的概率是比较小的,因此尽可能的会直接做下去,知道提交的时候去锁定,但是有可能会遇到冲突。

 一种可靠的乐观锁的实现是使用多版本控制(multi-version concurrency control),即在每一行加一个version属性,修改这一行时将version加1,写回数据库要检查当地前的version值是否还是获取时候的值,如果海华丝,说明在此期间没有修改,commit即可,如果不是,说明在此期间已经有修改了,当前事务获取的数据已过期,事务失败。

悲观锁(Pessimistic Concurrency Control):先取锁再访问

可重复读的两种实现方式:(1)悲观锁 (2)多版本并发控制MVCC 
隔离级别 写入锁 读取锁 范围锁
未提交读      
已提交读 YES    
可重复读 YES YES  
可序列化 YES YES YES

参考link: 

[1]http://zh.wikipedia.org/wiki/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BA%8B%E5%8A%A1

[2]http://zh.wikipedia.org/wiki/%E4%BA%8B%E5%8B%99%E9%9A%94%E9%9B%A2

[3]https://www.byvoid.com/blog/rdbms-isolation-lock-concurrency

[4]http://tech.meituan.com/innodb-lock.html

猜你喜欢

转载自juzy-xie.iteye.com/blog/2146562
今日推荐