文章目录
理解事务
事务保证了数据库将从一种一致性状态转移到另一种一致性状态,事务一般对于一组操作,这组操作的执行是原子的,要么全部完成要么全部失败,而且一旦提交必然能够保证对数据库永久性的改变,即使数据库发生故障也可以恢复数据。而且事务之间应该是独立。
事务具体体现在ACID四个特性。
四个特性及innoDB的实现
【1】atomic原子性:一个事务中的所有操作都是一个不可分割的工作单元,要么全部成功,要么全部失败。这个工作单元中的任何一个操作失败,所有已经执行的操作都应该被撤销。
【2】consistency一致性:事务开始前和结束后,数据库的完整性不被破坏。事务将数据库从一个一致性转变为下一种一致性状态,因此事务是一致性的单位。
【3】isolation隔离性:事务提交前对其他事务不可见,一个事务的执行不受到其他事务的影响。
【4】durability持久性:事务一旦提交,就是永久性的改变,即使系统故障也可以恢复,持久性保证事务系统的高可靠性。
原子性
原子性是基于 undo log 和 锁 实现的。锁本质上就是数据行上的一个变量,如果其他事务发现当前此记录被上锁便不能继续对其上锁(这里指互斥锁),同时如果执行事务的过程中出现所谓,便可以通过undo log回滚到事务开始之前的一致性状态。
持久性
持久性记录redo log实现。一旦事务提交,便会刷新重做日志,重做日志记录的就是对页面的具体操作,即使脏页还没有刷新到表空间而发生宕机,恢复时可以直接读取redo log进行恢复,默认情况下,事务提交时会调用fsync()将redo log buffer中的内容同步到磁盘。
redo log写入时脏页并没有同步到磁盘,但是redo log记录了对哪些页执行什么操作,因此即使内存中的脏页数据丢失就可以恢复(除非页本身收到损坏)
Redo log用于崩溃恢复。而binlog用于基于时间点的恢复,还可以用于主从复制
隔离性
隔离性侧重研究不同事务之间的互相影响(干扰的程度)。通常使用锁机制保证两个写事务之间的隔离性,通过MVCC机制保证读写事务之间的隔离性。
一致性
一致性指的是事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。
一致性是事务追求的最终目标,前面的三个性质都是为了保证数据库状态的一致性、同时还需要应用层的保证。
事务本质上是为了服务应用层而产生的。AID是手段,而C是目的。一致性就是应用系统借助AID从一个正确的状态到达另一个正确的状态。AID是数据库的特征,而C依赖于应用层、开发者。而正确的状态就是满足预定的约束的状态。
事务的开启与提交
mysql命令行的默认设置下,事务都是自动提交的(执行完SQL语句之后就会执行commit)。
【1】禁用当前会话的自动提交(1代表自动提交,0代表手动提交)
SET @@autocommit = 0;
【2】通过start transaction 或 begin 开始一个事务
还可以通过savepoint设置一个保存点,当发起回滚的时候仅仅回滚到保存点,而保存点之前的工作不受影响。
SET autocommit=0;
START TRANSACTION;
DELETE FROM account WHERE id=25;
SAVEPOINT a; -- 设置保存点
DELETE FROM account WHERE id=28;
ROLLBACK TO a; -- 回滚到保存点
在自动提交模式下,如果没有start transaction显示地开启一个事务,那么没有sql语句会被当做一个事务执行提交操作。而auto commit是针对连接的,修改某个连接不会影响其他连接。
权限管理语句、mysql架构修改语句、DDL语句(alter、drop、create、truncate等)会执行一个隐式的commit操作。格外注意:truncate table和delete虽然可以达到同样的效果,但是前者是不可以被回滚的。
innoDB存储引擎中可以查询关于事务的统计信息(只有显示提交的事务才会被统计)
show global status like 'com_commit'
show global status like 'com_rollback'
每秒事务请求数question per second (QPS) = com_commit + com_rollback
每秒事务处理能力transaction per second(TPS)= QPS / time
锁
数据库的锁都是基于索引实现的,如果SQL命中索引,锁住的是命中条件内的索引节点(行锁),否则锁定的是整个索引树(表锁&#x