MySQL-事务

192 阅读3分钟

ACID

原子性:

事务里面的操作要么全部成功并提交,要么失败就回滚

一致性:

事务只有在commit后,对数据库进行的操作才会生效

隔离性:

事务所做的修改在最终提交以前,对其它事务是不可见的

持久性:

事务提交后,其所做的修改就永久保存到数据库中

隔离级别

READ UNCOMMITTED(未提交读)

事务中的修改,即使没有提交,对其他事物也都是可见的。会导致脏读(T1修改数据后,T2读取,然后T1回滚,T2此刻的数据就是脏读)

READ COMMITTED(提交读)

事务从开始到提交之前,所做的任何修改对其它事务都是不可见的。该级别也叫做不可重复读,因为两次执行同样的查询,可能会得到不一样的结果。

REPEATABLE READ(可重复读)

REPEATABLE READ解决了脏读的问题。该级别保证在同一个事务中多次读取同样记录的结果是一致的。但是无法解决幻读。幻读,指当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。InnoDB通过多版本并发控制解决幻读的问题。

可重复读是MySQL的默认事务隔离级别

SERIALIZABLE(可串行化)

SERIALIZABLE是最高的隔离级别。通过强制事务串行执行,避免了幻读

死锁

死锁是指两个或者多事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象

为了解决死锁,数据库系统实现了各种死锁检测和死锁超时机制。

InnoDB目前处理死锁的方法是,将持有最少行及排它锁的事务进行回滚。

锁的行为和顺序是和存储引擎相关的。以同样的顺序执行语句,有些存储引擎会产生死锁,有些则不会。死锁的产生有双重原因:1、数据冲突 2、存储引擎实现方式导致

事务日志

使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中,而不用每次都将修改的数据本身持久到硬盘。事务日志采用的是追加的方式,因此写日志的操作是磁盘上一小块区域内的顺序I/O,而不像随机I/O需要在磁盘的多个地方移动磁头,所以采用事务日志的方式相对来说要快得多。

MySQL中的事务

MySQL提供了两种事务型的存储引擎:InnoDB和NDB Cluster

自动提交

通过命令

SET AUTOCOMMIT =1;

开启事务。 1或者ON,0表示关闭或者禁用

隔离级别

通过命令

SET TRANSACTION ISOLATION LEVEL

设置隔离级别 比如

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

隐式和显示锁定

InnoDB采用的是两阶段锁定协议。在事务执行过程中,随时都可以执行锁定,锁只有在COMMIT或者ROLLEBACK的时候才会释放,并且所有的琐事在同一时刻被释放。InnoDB会根据隔离级别在需要的时候自动加锁

显示锁定

  • SELECT ... LOCK IN SHARE MODE (读锁)
  • SELECT ... FOR UPDATE(写锁)