文章目录
一、事务是什么?
事务其实就是一组DML(insert、delete、update)语句的集合。MySQL数据库InnoDB存储引擎支持事务,MyISAM不支持。而且MySQL的事务默认是自提交模式,如果想要开启事务,必须以begin命令开始,以commit或者rollback命令结束。
二、事务的特性
1.原子性(Atomicity)
事务的原子性是指事务中包含的所有操作要么都做,要么都不做,保证数据库是一致的。
甲账户向乙账户转账1000元,则先将甲账户减少1000元,再将乙账户增加1000,这两个动作要么都提交,要么都回退,不可能发生一个有效另一个无效的情况。
2.一致性(Consistency)
一致性是指数据库中的数据在事务操作前和事务处理后必须都满足业务规则约束。
甲乙账户的总金额在转账前和转账后必须一致,如有不一致,则必须是短暂的,且只有在事务提交前才会出现的。
3.隔离性(Isolation)
隔离性是数据库允许多个并发事务同时对数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。
在甲、乙之间转账时,丙同时向甲转账,若同时进行,则甲、乙之间的一致性不能得到满
足。所以在甲、乙事务执行过程中,其他事务不能访问(修改)当前相关的数值。
4.持久性(Durability)
事务处理结束后,对数据的修改就是永久的,即便系统发生故障也不会丢失。
在事务的四大特性中,我们主要研究隔离性,知识点就是事务的隔离级别。
三、事务语句
事务开启语句是由begin或者start transaction(read write|read only)命令来开始的,或者把自提交特性关掉(执行set autocommit=0命令)。
事务结束语句通常使用commit或者rollback显示结束。
commit代表提交事务,使得已对数据库做的所有修改成为永久性。
rollback代表回滚事务,撤销正在进行的所有未提交的修改。
当然事务除了显示提交(commit)和回滚(rollback)的操作,还有隐式提交和回滚。隐式提交可以是DDL语句的操作或者再次输入begin和start transaction命令。隐式回滚可以退出会话、连接超时或者关机等。
事务不是自动提交的,而MySQL数据库是自提交模式(autocommit=1)。那到底需不需要把MySQL的自动提交手动关闭呢?set autocommit=0之后可以不用一个事务一次提交了,可以多个事务一起提交,提高了每秒处理事务的能力。但如果在这个过程中有某个事务一直没有提交,就会导致行锁等待的现象。其他事务必须得等这个事务提交之后,才可以继续提交,这样就严重影响数据库的TPS值了。
四、事务隔离级别
MySQL InnoDB存储引擎实现SQL标准的4种隔离级别,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。
MySQL数据库通过show variables like '%tx isolation%'
命令来查看当前数据库的隔离级别。
可以通过set globallsession transaction isolation level
命令修改全局或者当前会话的事务隔离级别。
目前MySQL版本默认的隔离级别是REPEATABLE-READ。
读未提交(read uncommitted)
在其中一个事务中,可以读取到其他事务未提交的数据变化。这种读取其他会话还没提交的事务,叫作脏读现象。
读已提交(read committed)
在其中一个事务中,可以读取到其他事务已经提交的数据变化。这种读取也可以叫作不可重复读,允许幻读现象的发生,是Oracle数据库默认的事务隔离级别。
可重复读(repetable read)
它是MySQL默认的事务隔离级别一在其中事务中,直到事务结束前,都可以反复读取到事务刚开始时看到的数据,并一直不会发生变化,避免了脏读、不可重复读和幻读现象的发生。
串行(serializable)
在每个读的数据行上都需要加表级共享锁,在每次写数据时都要加表级排他锁。这就会造成InnoDB的并发能力下降,大量的超时和锁竞争就会发生。
五、脏读、不可重复读、幻读、可重复读现象
脏读
脏读是在事务隔离级别读未提交中出现的现象。一个事务读取到了其他事务还没有提交的数据。
在读未提交隔离级别下,操作如下:
不可重复读
不可重复读是指在其中一个事务中,读取到了其他事务针对旧数据的修改记录(常见的操作就是update或者delete语句)。
幻读
幻读是指在其中一个事务中,读取到了其他事务新增的数据,仿佛出现了幻影现象(常见的操作就是insert语句)。这种读的现象允许出现在读已提交的事务隔离级别中。
会话A,在隔离级别RC模式下,在事务中执行一条insert语句操作,并且进行了提交:
可重复读
可重复读是MySQL数据库默认的事务隔离级别。它消除了脏读、不可重复读、幻读现象,很好地保证了事务的一致性。
会话A,在RR隔离级别下,在事务中新增了一条数据,并且已经对数据进行提交:
truncate和delete的区别
truncate是DDL语句操作,delete是DML语句操作,它们的共同点都是清空表内的数据,但truncate在事务中不能被回滚,而且truncate会清空表的自增属性。
第一点,truncate不能回滚,delete可以回滚
第二点,truncate清空表的自增id属性,从l重新开始记录,而delete则不会。