文章目录
  1. 1. 特性(ACID)
  2. 2. 隔离级别
    1. 2.1. 幻读和不可重复读区别
  3. 3. 死锁
  4. 4. 事务日志
  5. 5. Mysql中的事务
    1. 5.1. 自动提交
  6. 6. 事务中混合使用存储引擎
  7. 7. 隐式和显示锁定
  8. 8. 多版本并发控制(MVCC)
  9. 9. 事务操作语句

事务是数据库中的一个重要特性,首先就给大家介绍一下这个。事务就是一组原子性的SQL查询,或者说一个独立的工作单元。对于事务内的语句,要么全部执行成功,要么失败回滚都不执行。

特性(ACID)

  1. 原子性(atomicity)

    事务在执行性,要做到“要么不做,要么全做!”,就是说不允许事务部分得执行。即使因为故障而使事务不能完成,在rollback时也要消除对数据库得影响

  2. 一致性(consistency)

    事务得操作应该使使数据库从一个一致状态转变倒另一个一致的状态!就拿网上购物来说吧,你只有即让商品出库,又让商品进入顾客得购物篮才能构成事务!

  3. 隔离性(isolation)

    如果多个事务并发执行,应像各个事务独立执行一样!就是一个事务所做的修改再最终提交之前,其他事务是不可见的。

  4. 持久性(durability)

    一个成功执行得事务对数据库得作用是持久的,即使数据库应故障出错,也应该能够恢复!

事务处理过程中额外的安全性,也会需要数据库系统做更多的额外工作。满足ACID的数据库通常需要更强的CPU处理能力、更大的内存和更多的磁盘空间。

隔离级别

隔离性远比想象的复杂,SQL中定义了四种隔离级别。

  1. READ UNCOMMITTED

    最低级别的隔离,通常又称为dirty read,它允许一个事务读取还没commit的数据,这样可能会提高性能,但是dirty read可能不是我们想要的。从性能上来说,该级别不会比其他好太多,但缺乏很多其他级别的好处,一般很少使用。

  2. READ COMMITTED

    在一个事务中只允许已经commit的记录可见,如果session中select还在查询中,另一session此时insert一条记录,则新添加的数据不可见。这个级别也叫做不可重复读(nonrepeatable read),大多数数据库默认级别(但Mysql不是)。

  3. REPEATABLE READ

    在一个事务开始后,其他session对数据库的修改在本事务中不可见,直到本事务commit或rollback。在一个事务中重复select的结果一样,除非本事务中update数据库。这种隔离级别会导致引发幻读(多版本并发控制可以解决这个问题)。

    mysql默认隔离级别。

  4. SERIALIZABLE

    最高级别的隔离,只允许事务串行执行(单线程)。为了达到此目的,数据库会锁住每行已经读取的记录,其他session不能修改数据直到前一事务结束,事务commit或取消时才释放锁。

幻读和不可重复读区别

不可重复读是读取到了别人对表中的某一条记录进行了修改,导致前后读取的数据不一致。 幻读是前后读取到表中的记录总数不一样,读取到了其它事务插入的数据。

不可重复读的重点是修改,同样的条件, 你读取过的数据, 再次读取出来发现值不一样了

幻读的重点在于新增或者删除,同样的条件, 第1次和第2次读出来的记录数不一样

死锁

死锁是指两个或者多个事务在同一个资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。当多个事务视图以不同顺序锁定资源时,就可能产生死锁;多个资源同时锁定同一个资源也可能产生死锁。

数据库系统实现了各种死锁检测和死锁超时机制。InnoDB目前处理死锁的方法是:将持有最少行级排他锁的事务进行回滚。

死锁产生有双重原因:一是真正的数据冲突;二是存储引擎的实现方式。

事务日志

是用事务日志可以提高事务处理的效率。

使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到持久的硬盘上的事务日志中,而不是每次都将修改数据本身持久到硬盘。事务日志采用的是追加的方式,因此写日志的操作是硬盘上一小块区域内的顺序I/O,而不像随机I/O需要在磁盘的多个地方移动磁头,所以采用事务日志相对要快的多。事务日志持久之后,内存中被修改的数据在后台慢慢地刷回到磁盘。目前大多数存储引擎都是这样实现的,我们通常称为预写式日志(Write-Ahead Logging),修改数据需要写两次磁盘。

Mysql中的事务

提供了两种事务性的存储引擎:InnoDB和NDB Cluster。还有一些第三方存储引擎也支持。

自动提交

默认采用自动提交(AUTOCOMMIT)

SET AUTOCOMMIT = 1(或者ON)表示启用,=0表示所有的查询都是在一个事务中。

事务中混合使用存储引擎

是不可靠的。

隐式和显示锁定

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

InnoDB也支持显示锁定。

Select 。。。。LOCK IN SHARE MODE
SELECT .....FOR UPDATE

多版本并发控制(MVCC)

大多数事务性数据库都不是简单的行级锁,一般都是实现多版本并发控制(MVCC)。

MVCC可认为是锁的变种,多数情况下可以避免加锁操作。

MVCC通过保存数据在某个时间点的快照来实现的。也就是说,不论需要执行多长时间,每个事务看到的数据都是一致的。

不同存储引擎的MVCC的实现是不同的,典型的有乐观和悲观两种。

InnoD的MVCC通过在每行记录后面保存两个隐藏的列来实现。这两个列,一个保存了行的创建时间,一个保存行的过期时间(或删除时间)。当然存储的不是时间值,而是系统版本号。没开始一个新的事务,系统版本号都会自动增加。

使用这两个额外的系统版本号,使大多数读操作都可以不用加锁。不足之处是每行记录都需要额外的存储空间,需要做更多的行检查工作,以及一些额外的维护工作。

MVCC只在READ COMMITTED、REPEATABLE READ两个级别下可以工作,其他不兼容。

事务操作语句

  1. START TRANSACTION:

    开始事务,autocommit设为0,如果已经有一个事务在运行,则会触发一个隐藏的COMMIT

  2. COMMIT:

    提交事务,保存更改,释放锁

  3. ROLLBACK:

    回滚本事务对数据库的所有更改,然后结束事务,释放锁

  4. SAVEPOINT savepoint_name:

    创建一个savepoint识别符来ROLLBACK TO SAVEPOINT

  5. ROLLBACK TO SAVEPOINT savepoint_name:

    回滚到从savepoint_name开始对数据库的所有更改,这样就允许回滚事务中的一部分,保证更改的一个子集被提交

  6. SET TRANSACTION:

    允许设置事务的隔离级别

  7. LOCK TABLES:

    允许显式的锁住一个或多个table,会隐式的关闭当前打开的事务,建议在执行LOCK TABLES语句之前显式的commit或rollback。我们一般所以一般在事务代码里不会使用LOCK TABLES

文章目录
  1. 1. 特性(ACID)
  2. 2. 隔离级别
    1. 2.1. 幻读和不可重复读区别
  3. 3. 死锁
  4. 4. 事务日志
  5. 5. Mysql中的事务
    1. 5.1. 自动提交
  6. 6. 事务中混合使用存储引擎
  7. 7. 隐式和显示锁定
  8. 8. 多版本并发控制(MVCC)
  9. 9. 事务操作语句