事务概念:事务是是一组原子性的sql查询。
其中要注意的是 ‘原子性’ 这三个字我们现在知道原子还能再分,但这里的原子性是更接近原子诞生时的概念——物质的基本组成=不可再分。所以这句话更白话一点是“事务是一组不可分割执行只能整体成功或者整理失败的sql查询”
注:1、事务在引擎层实现的 2、Mysql不支持InnoDB支持
事务属性
除了原子性(atomicity)之外事务还有另外三个特性:
一致性(consistency):数据库总是从一个一致性的状态转换到另一个一致性的状态
注:翻译成白话就是事务在执行的过程中是不会改变数据库的要不是成功然后改变数据库要不失败什么都改变不了
持久性(durability):嗯,事务成功就会改变数据库数据。(感觉有点废话)
隔离性(isolation):笼统来说就是事务在运动,说错了是在运行的时候会有类似出神的状态,别人看不到这个过程,等他搞完得出结论了才会表现行动。
其他三个特性没什么好说的,下面仔细说说隔离性中的隔离级别:
隔离级别
共有四种隔离级别
隔离级别 | 脏读 | 不可读 | 幻读 | 加锁读 |
---|---|---|---|---|
read uncommitted(读未提交) | Y | Y | Y | N |
read committed(读提交) | N | Y | Y | N |
repeatable read(可重复读) | N | N | Y | N |
serializable(串行化) | N | N | N | Y |
隔离级别与发生问题解释:
read uncdmmitted(读未提交):
事务中的修改即使没有提交,对其它事务也是可见的。(类似读心术,你脑子里面想的东西就算没表现出来别人知道,非常恐怖是不是所以是个大bug)
实际中的示例:你去菜市场买菜,挑了两斤菜给阿姨称。本来是3块钱一斤的菜,阿姨手抖称成2块钱一斤。你以为今天大减价。不过,阿姨即时回滚了事务,按3块钱重新称了下得出:“小x,6块哈!”。 你看到的阿姨按错的2块钱就是脏读。
read cdmmitted(读提交,不可重复读):
一个事务开始时,只能“看见”已经提交的事务所做的修改。(这是个没有读心术的世界你脑袋里面想的东西除非你做出来否则别人是不会知道的)
实际中的示例:你去超市买菜,走到藕前面本来想买一个,这时听到那边虾有打折立马赶过去。等你赶过去时虾已经卖光了,你垂头丧气的回来买藕。结果回到藕面前的时候发现藕也卖光了。于是你什么都没买的走出了超市。
在这里你第一次看见藕是有藕的(事务开启),但当别的事务插进来时(买虾),等这个事务(买虾)进行完,再查询藕时就卖光了(事务进行中数据被修改)。这个就是不可重复读
repeatable read(可重复读):
该级别中保证了在同一个事务中多次读取同样的记录结果是一致的。
实际中的示例:你去超市买菜,走到藕前面本来想买一个,这时听到那边虾有打折,你马上拿了一个藕放到购物车里。等你赶过去时抢了一把虾。结果你买齐了材料,晚上做香锅吃。这里就解决的不可重复读的问题。
幻读
repeatable read 可以防止update操作但是不可以防止insert。所谓的幻读是当某个事物在读取某个范围记录时,另一个事务又在改范围内插入了新的记录
你和老婆一起去超市买菜,把虾和藕放在购物车里。这时你去零食区买东西,老婆觉得虾买的太少了就再买了一袋。你买完零食结账,发现莫名其妙多了一袋虾,像是产生幻觉了。
怎么解决这种好像见鬼的问题呢?
serializable(串行化)
最高隔离级别,强制将事务串行话执行。
示例:在上回结账见鬼的事情发生了后,你想出了一个办法就是买了个锁把购物车盖子锁起来。这样要放什么东西都要在你眼皮底下才行了(强制事务串行),妈妈再也不用当心结账见鬼的问题了。嗯,于是你微笑着拿出锁的那一刻,就被老婆的平底锅砸了。(太神经病了,所以一般是不用这个级别的)
注:大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。Mysql的默认隔离级别是Repeatable read。
隔离级别查看
查看当前会话隔离级别 : select@@tx_isolation
查看系统当前隔离级别 : select @@global.tx_isolation;
隔离级别设置
设置当前会话隔离级别 : set session transaction isolation level repeatable read;
设置系统当前隔离级别 : set global transaction isolation level repeatable read;