mysql事务与锁
2017-03-08 10:39
567 查看
事务控制
start transaction|begin [work] commit [work] [and [no] chain] [[no] release] rollback [work] [and [no] chain] [[no] release] set autocommit={0|1}
分布式事务只支持InnoDB存储引擎。
两阶段
事务ACID
原子性(Atomicity):要么全执行,要么全不执行
一致性(Consistent):事务开始和完成时,数据必须保持一致状态
隔离性(Isolation):不受外部并发操作影响
持久性(Durable):数据修改时永久性的
术语
更新丢失:后面的更新覆盖了前面的更新
脏读:修改未提交之前,另一个事务去读了
不可重复读:一个事务内,两个时间点读的数据不一致
幻读:一个事务按照相同的查询条件读取以前检索过的数据,却发现其他事务插入了满足其查询条件的数据
事务的隔离级别
级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
可读取未确认Read uncommitted | 可能 | 可能 | 可能 |
可读取确认Read committed | 不可能 | 可能 | 可能 |
可重复读 | 不可能 | 不可能 | 可能 |
可串行化(序列化)Serializable | 不可能 | 不可能 | 不可能 |
mysql锁
各存储引擎的锁MyISAM和MEMORY存储引擎采用的是表级锁
BDB存储引擎采用的是页面锁,但也支持表级锁
InnoDB存储引擎支持行级锁,也支持表级锁
锁 | 特性 |
---|---|
表级锁 | 开销小,加锁快;不会出现死锁;锁定粒度大,发生冲突的概率最高,并发度最低。 |
行级锁 | 开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高 |
页面锁 | 开销和加锁时间介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般 |
查询表级锁争用情况
show status like 'table%';
如果Table_locks_waited的值比较高,则说明存在着较严重的表级锁争用情况。
表级锁的锁模式
表共享读锁
表独占写锁
MyISAM总是一次获得sql语句所需要的全部锁,这是MyISAM表不会出现死锁的原因。
并发插入
MyISAM存储引擎有一个系统变量concurrent_insert
concurrent_insert值 | 说明 |
---|---|
0 | 不允许并发插入 |
1 | 如果表中没有空洞,MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记录 |
2 | 无论MyISAM表中有没有空洞,都允许在表尾并发插入记录 |
通过设置启动参数low-priority-updates使MyISAM引擎默认给予读请求以优先的权利
通过执行命令set low-priority-updates=1,使得该连接发出的更新请求优先级降低
通过指定insert,update,delete语句的low_priority属性,降低该语句的优先级
查询优先可以解决查询相对重要的应用(用户登录)中读锁等待严重的问题。读写冲突,可以给系统参数max_write_lock_count设置一个合适的值,当一个表的读锁达到这个值后,mysql就暂时将写请求的优先级降低,给读进程一定获得锁的机会。一些需要长时间运行的查询操作,也会使写进程”饿死”,尽量避免出现长时间运行的查询操作,对于复杂的查询,不要一个sql写完,否则执行时间可能较长。在可能的情况下,尽量用中间表等措施对sql语句做一定的分解,使每一步查询时间都比较短,从而减少锁冲突。统计类的sql,可以安排在夜间空闲时刻执行。
InnoDB锁问题
InnoDB与MyISAM的最大不同有两点
支持事务
采用行级锁
获取InnoDB行锁争用情况
show status like 'innodb_row_lock%'
如果InnoDB_row_lock_waits和InnoDB_row_lock_time_avg的值比较高,则锁争用比较严重。
查看锁等待情况
select * from innodb_locks \G;
设置InnoDB Monitors观察锁冲突情况
create table innodb_monitor(a int) engine=innodb; show engine innodb status\G; drop table innodb_monitor;
InnoDB的行锁
共享锁(S):类似读锁
排他锁(X):类似写锁
表锁,意向锁
意向共享锁(IS)
意向排他锁(IX)
当前模式\是否兼容\请求锁模式 | X | IX | S | IS |
---|---|---|---|---|
X | 冲突 | 冲突 | 冲突 | 冲突 |
IX | 冲突 | 兼容 | 冲突 | 兼容 |
S | 冲突 | 冲突 | 兼容 | 兼容 |
IS | 冲突 | 兼容 | 兼容 | 兼容 |
InnoDB行锁是通过给索引上的索引项加锁来实现的,如果没有索引,InnoDB将通过隐藏的聚簇索引来对记录加锁,InnoDB行锁分为3中情形。
Record lock:对索引项加锁
Gap lock:对索引项之间的”间隙”、第一条记录前的”间隙”或最后一条记录后的”间隙”加锁。
Next-key lock:前两种的组合,对记录及前面的间隙加锁。
InnoDB这种行锁实现特点意味着,如果不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,实际效果跟表锁一样。
next-key锁
范围条件检索数据,符合条件的数据行会加锁,条件范围内的间隙也会加锁,比如:select * from emp where empid>100 for update;其中,empid的值分别是1,2,…,100,101,InnoDB不仅会对符合条件的101记录加锁,也会对empid大于101(这些记录不存在)的间隙(GAP)加锁。一方面为了防止幻读,另一方面,为了满足其恢复和复制的需要。注意:范围更新,无论出于那个隔离级别都使用next-key锁。
相关文章推荐
- MySql中的事务问题
- MySQL 4.1.0 中文参考手册 --- 6.7 MySQL 事务与锁定命令
- mysql事务处理
- PHP java MySQL 与 MsSQL 中的事务
- MYSQL的事务处理功能!
- 用新PHP插件实现MySQL为基础的事务
- ASP.net(c#)+MySql 事务的使用方法
- MYSQL集群与INNODB事务处理的对比总结
- MyEclipse及Hibernate/MySQL开发的事务处理及UML图示范
- 正好整理了一下,自己做了个连接数据库的组件,支持SQLSERVER,ACCESS,ORACLE,FoxPro,MySql,IBM DB2,DBF等数据库,并且支持事务处理
- Mysql支持事务处理
- MySQL 事务与锁定命令
- mysql下的简单事务
- PHP+MySQl的事务处理
- PHP操作MYSQL用“事务”的例子
- 让MYSQL支持事务处理
- MySQL 5.0 存储过程 (2) 事务 & SQLEXCEPTION
- mysql 事务
- 【搜集】MYSQL高级特性 -- 事务处理
- Mysql InnoDB 事务模式与锁定