首先打算 好好了解一下它的机制。
隔离
首先 sql 规范有四种隔离级别。
1.red uncommited (读取未提交内容) :事务未提交也能读
2.red commited(读取提交内容) :读取提交后的内容。 绝大部分数据库默认用这个。
3. repeatable read(可重复读):mysql 默认用这个。
4.serializable(串行化):最安全也是最耗性能的。所有事务是排序进行的。一个执行完了才能下一个。
隔离级别 | 脏读可能 | 不可重复读可能 | 幻读可能 | 加锁读 |
red uncommited | 是 | 是 | 是 | 否 |
red commited | 否 | 是 | 是 | 否 |
repeatable read | 否 | 否 | 是 | 否 |
serializable | 否 | 否 | 否 | 是 |
事务
对于事务。需要注意的是非事务表的存在。有些表示非事务表。如:InnoDB表和MyISAM表。如果在事务中处理了事务表和非事务表。然后出错回滚。非事务表将不会回滚。
有时候会有一个警告提示。而绝大部分不会有任何提示。
锁分显示锁和隐式锁。一般的对于数据的操作。都是隐式锁。不过可以通过语句显示加锁。如:
select ........lock in share mode;
select ...... for update;
等等。
并发控制
数据库对于数据的处理不是简单的加锁处理的。是通过一种“mvcc(多版本并发控制)”来处理的。 各个数据库对于mvcc的实现是不同。
利用InnoDB模式下的简化mvcc举例说明一下
InnoDB 通过为每个数据行添加两个隐含值来实现mvcc。这两个值记录着行的创建时间和过期时间(删除时间)。每一行都记录着事件发生时的系统版本号,用来替代时间发生的实际时间。每一次 开始一个事务。都会吧系统版本号递增。每个事务都会保存他在开始时候的“当前系统版本”的记录。而每个查询都会根据事务的版本号,检查每行数据的版本号。下面看下隔离级别为 repeatable read的时候、mvcc在实际操作中的应用方式。
select
检查每行数据。确保符合2点
1.只查找版本号小于或者等于当前版本号的。(小于版本说明是之未改变的。等于说明是这个事务创建的)
2.确保删除版本是未定义的或者大于事务版本的。(未定义说明没被删除。大于版本说明是被之后的其他事务删除的。)
intsert
创建行 赋予当前版本号
delete
将删除删除版本号设置为当前版本号
update
1。将删除删除版本号设置为当前版本号 。
2。拷贝旧行。更新值。设置创建版本号。
这样 很明显。缺点就是有额外的记录行。(这些记录行肯定有妥善的方法清理。我不懂怎么处理。)好处就是不必加锁。
mvcc模式只在red commited 和repeatable read隔离级别下有效。 red uncommited级别永远读取最新的。而serializable是加锁的。
总结一下各种加锁策略性能以及引擎支持:
加锁策略 | 并发 | 系统开销 | 引擎 |
表级加锁 | 最低 | 最低 | MyISAM、merge、memory |
行级加锁 | 高 | 高 | NDB Cluster |
MVCC | 最高 | 最高 | InnoDB、Falcon、PBXT、solidDB |
通过命令 show table status like ‘user’ 可以获得user表的信息 包括引擎
MyISAM
MyISAM引擎是mysql默认引擎。