MYSQL事务基本特性以及隔离级别

MYSQL事务基本特性以及隔离级别

事务的特性 : ACID

Atomicity 原子性,事务不可分割的,是最小的操作单位,事务的所有的操作要么全部成功,要么全部失败

Consistency 一致性,多哥客户端进行同时访问的时候,通过事务可以对多个客户端保持数据的一致性,

Isolation 事务的隔离性 多个事务并发操作的时候,多个事务之间互不影响,彼此独立

Durability 事务的持久性: 数据的该变通过事务的提交可以永久的保存在数据库中,即使数据库发生故障也不应该对其有任何影响。

并发事务的问题

多个事务并发运行,经常会操作相同的数据库来完成各自的任务(多个用户对同一数据进行操作)并发虽然是必须的,但可能导致一下的问题

1. 更新丢失(Lost update)

当多个事务选择同一行操作,并且都是基于最初选定的 值由于每个事务都不知道其他事务的存在,就会发生更新覆盖的问题。类比git的提交冲突

2. 脏读(Dity Read)

当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库,这个时候另外的一个事务访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的就是这个数据的脏数据,这就叫脏读。脏读导致一个事务读取了被其他事务修改但还未提交的数据。

3. 不可重复读(Non—Repeatable Read)

  • 是指一个事务读取数据库中的数据后,另一个事务则修改或删除数据,当第一个事务再次执行同一查询时,就会发现数据已经发生了改变,这就是不可重复读。不可重复读所导致的结果就是一个事务前后两次读取的数据不相同,可以读取到其他事务更新/删除后的数据。
  • 即不可重复读发生在一个事务执行两次或两次以上的相同查询时,查询结果不一致。这通常是由于另一个并发事务在两次查询之间修改/删除并提交了符合查询条件的数据。
  • 如:事务T1按照条件读取一批记录,紧接着事务T2修改并提交了T1刚刚读取的那一批记录,然后T1再一次查询,发现与第一次读取的记录不同。

4. 幻读(Phantom Read 不一定会发生)

  • 是指一个事务读取数据库中的数据后,另一个事务则插入了数据数据,当第一个事务再次执行同一查询时,就会发现数据已经发生了改变,多出来了数据,这就是幻读。幻读所导致的结果就是一个事务前后两次读取的数据不相同,可以读取到其他事务新插入的数据。
  • 即幻读发生在一个事务执行两次或两次以上的相同查询时,查询结果不一致。这通常是由于另一个并发事务在两次查询之间插入并提交了符合查询条件的数据。
  • 如:事务T1按照条件读取一批记录,紧接着事务T2插入并提交了符合T1查询条件的记录,然后T1再一次查询,发现与第一次读取的记录不同。

3 事务的简单实现原理

  1. MySQL InnoDB 引擎通过undo log回滚日志来保证原子性。
  2. MySQL InnoDB 引擎使用 redo log重做日志 保证事务的持久性。
  3. MySQL InnoDB 引擎通过锁机制、MVCC 等手段来保证事务的隔离性( 默认支持的隔离级别是 REPEATABLE-READ )。
  4. 保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。

MySQL日志系统:redo log、binlog、undo log 区别与作用

4 事务的隔离级别

数据库允许多个事务的并行,事物的隔离级别就用来表示此事务与其他并行事务的工作隔离的程度。例如,此事务能否看到来自其他事务的未提交的写入?不同的数据库有不同的默认事务隔离级别。由于并行事务,不同的隔离级别可能会带来不同的数据访问现象/安全问题。换句话说,事务的隔离级别是根据是否会出现上面讲的的某些现象来区分的!

在SQL92标准中,针对大部分数据库定义了4个标准的事务隔离级别:

读未提交(Read Uncommitted):

就是一个事务可以并发的读取另一个未提交事务变更的数据。存在脏读、不可重复读、幻读的问题。

读已提交(Read Committed):

一个事务可以并发的读取另一个事务提交后的数据。解决了脏读问题,还有不可重复读和幻读的问题。Sql Server , Oracle的默认隔离级别。

可重复读(Repeatable Read):

一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。即事务在执行期间看到的数据前后必须是一致的。可能出现幻读。MySQL的默认隔离级别就是Repeatable Read。

实际上,mysql在默认的可重复读隔离级别下,mvcc的普通的查询是快照读,提供了一致性视图,不会看到别的事务插入的数据的,也就不存在所谓的“幻读”了,而如果使用当前读,那么则会加上行锁+Gap间隙锁,其他事务的插入操作则根本无法进行,因此实际上mysql的InnoDB引擎已经使用mvcc解决了幻读的问题(见《高性能MySQL》)。那么这里的幻读是什么呢?这里更多是指的oracle的操作,所以你用mysql测试的话,幻读很有可能测不出来。

当前读:select…lock in share mode (共享读锁)、select…for update、update语句、delete语句、insert语句。

序列化/串行化(Serializable):

Serializable 是最高的事务隔离级别,在该级别下,事务通过加锁的方式直接避免并行访问,可以避免脏读、不可重复读与幻读问题,严重影响程序性能。读的时候加共享锁,也就是其他事务可以并发读,但是不能写。写的时候加排它锁,其他事务不能并发写也不能并发读。

Oracle默认的隔离级别是read committed,还支持SERIALIZABLE。MySQL默认隔离级别: Repeatable Read,并支持全部四种级别。

可以用show variables like 'transaction_isolation';命令来查看当前的隔离级别

在不同的隔离级别下,数据库行为是有所不同的。事务的隔离级别设置越高,异常就出现的越少,但并发效果就越低,事务的隔离级别设置越小,异常出现的越多,并发效果越高。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值