MYSQL 事务及并发事务概述

1 篇文章 0 订阅
0 篇文章 0 订阅

一、事务

首先来看一下事务的概念:一组DML语言作为最小的原子单元,要么同时成功,要么同时失败。对于事务性的数据库,存储引擎一般使用的是innoDB。
简单来说,事务就是在一组SQL组成一个大的集合来执行,不会存在只有一部分执行成功,另一部分失败。事务存在两个状态,commit提交,rollback回滚。
这里,我们使用银行转账的情况来解释。
比如,有两个账号,分别为Mike和Tom,Mike账户里有1000元,Tom账户里有1500元。Mike要给Tom转100块钱,数据库会执行如下的执行语句:

    update bank set money = money - 100 where id = 1; 
	update bank set money = money + 100 where id = 2;

这里就会发生一种情况,在执行完第一个SQL语句后,第二个SQL语句出现错误,那么,Mike损失了100元,现在为900,但是Tom却没有得到100元,还是1500。这个时候,就需要事务的存在,来避免这种情况的存在。
(oracle数据库中,任何一个修改语句都作为一个单独事务,而MYSQL中,采用了自动提交修改事务的方式)
事务具有四大特性,即原子性、一致性、隔离性、持久性。
原子性: 一组操作不可分割,必须全部成功或者失败。
一致性: 数据及其结构,约束等信息,在事务执行前后保持一致。
隔离性: 并发事务之间互相不干扰。
持久性: 事务执行完成,数据将持久化到数据库。

二、并发事务

并发事务可以类比线程的概念,即同时有很多事务在运行。
而并发事务会造成如下几个问题:

  1. 脏读
  2. 不可重复读
  3. 幻读

脏读:一个事务读取到另一个事务未提交的数据。比如,Mike在给Tom转钱的时候,虽然已经转走了100,但是这个事务没有提交,依然可能会存在rollback的情况,所以当另一个事务来对Mike账户进行读取的时候,会读取到900元,但是Mike账户的钱取决于转账事务的成功与否,这种并发事务读取数据的情况就叫做脏读。
不可重复读:一个事务在查询范围内,由另一个事务修改并进行事务提交,导致该事务在多次查询时出现数据不一致。这个就像它本身的名字一样,说的是多次读取的时候,可能其他事务已经对Mike的账户进行了转账,造成了第一次读取的数据和第二次读取的数据出现不一致的情况。
幻读:一个事务在查询范围内,由另一个事务添加或者删除记录并进行事务提交,导致该事务产生”幻行”。幻读是对数据量来说的,因为你在读取数据的时候,可能其他事务会添加和删除了记录,造成了读取数据量的偏差。

针对并发事务可能存在的问题,数据库提供了几种隔离级别:

① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。

② Repeatable read (可重复读):可避免脏读、不可重复读的发生。

③ Read committed (读已提交):可避免脏读的发生。经常使用。

④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。
  以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然级别越高,执行效率就越低。像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。

在MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read (可重复读);而在Oracle数据库中,只支持Serializable (串行化)级别和Read committed (读已提交)这两种级别,其中默认的为Read committed级别。

在MySQL数据库中查看当前事务的隔离级别:

select @@tx_isolation;

在MySQL数据库中设置事务的隔离 级别:

set  [glogal | session]  transaction isolation level 隔离级别名称;

set tx_isolation=’隔离级别名称;’	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值