当前位置:  数据库>mysql

MySQL InnoDB之事务与锁详解

    来源: 互联网  发布时间:2014-10-04

    本文导语:  引题:为何引入事务? 1>.数据完整性 2>.数据安全性 3>.充分利用系统资源,提高系统并发处理的能力 1. 事务的特征 事务具有四个特性:原子性(Atomiocity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),这四...

引题:为何引入事务?

1>.数据完整性

2>.数据安全性

3>.充分利用系统资源,提高系统并发处理的能力

1. 事务的特征

事务具有四个特性:原子性(Atomiocity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),这四个特性简称ACID特性。

1.1原子性

事务是数据库的逻辑工作单位,事务中包括的所有操作要么都做,要么都不做。

1.2 一致性

事务执行的结果必须是使数据库从一个一致性的状态变到另外一个一致性状态。

1.3 隔离性

一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对其他

事务是隔离的,并发执行的各个事务之间互相不干扰。

1.4 持久性

一个事务一旦成功提交,对数据库中数据的修改就是持久性的。接下来其他的其他

操作或故障不应该对其执行结果有任何影响。

2. MySQL的InnoDB引擎中事物与锁

2.1 SELECT …… LOCK IN SHARE MODE

会话事务中查找的数据,加上一个共享锁。若会话事务中查找的数据已经被其他会话事务加上独占锁的话,共享锁会等待其结束再加,若等待时间过长就会显示事务需要的锁等待超时。

2.2 SELECT ….. FOR UPDATE

会话事务中查找的数据,加上一个读更新琐,其他会话事务将无法再加其他锁,必须等待其结束。

2.3 INSERT、UPDATE、DELETE

会话事务会对DML语句操作的数据加上一个独占锁,其他会话的事务都将会等待其释放独占锁。

2.4 gap and next key lock(间隙锁)

InnoDB引擎会自动给会话事务中的共享锁、更新琐以及独占锁,需要加到一个区间值域的时候,再加上个间隙锁(或称范围锁),对不存在的数据也锁住,防止出现幻写。

备注:

以上2.1,2.2,2.3,2.4中描述的情况,跟MySQL所设置的事务隔离级别也有关系。

3.四种事务隔离模式

3.1 READ UNCOMMITED

SELECT的时候允许脏读,即SELECT会读取其他事务修改而还没有提交的数据。

3.2 READ COMMITED

SELECT的时候无法重复读,即同一个事务中两次执行同样的查询语句,若在第一次与第二次查询之间时间段,其他事务又刚好修改了其查询的数据且提交了,则两次读到的数据不一致。

3.3 REPEATABLE READ

SELECT的时候可以重复读,即同一个事务中两次执行同样的查询语句,得到的数据始终都是一致的。

3.4 SERIALIZABLE

与可重复读的唯一区别是,默认把普通的SELECT语句改成SELECT …. LOCK IN SHARE MODE。即为查询语句涉及到的数据加上共享琐,阻塞其他事务修改真实数据。

4. 验证事务与锁定示例

接下来,我们将以MySQL中的InnoDB引擎,解释其如何实现ACID特性,不同隔离级别下事务与事务之间的影响。示例表结构:

CREATE TABLE `account ` (

`ID` int(11) NOT NULL AUTO_INCREMENT,

`VACCOUNT_ID` varchar(32) NOT NULL,

`GMT_CREATE` datetime NOT NULL,

PRIMARY KEY (`ID`),

KEY `idx_VACCOUNT_PARAMETER_VACCOUNTID ` (`VACCOUNT_ID`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE utf8_general_ci;

然后向表account中写入10W条创建日期分布合理的帐号数据,以方便测试之用。

tx_isolation:SET GLOBAL tx_isolation='read-uncommitted' ID 事务1 事务1输出 事务2 事务2输出 1 START TRANSACTION;       2 SELECT VACCOUNT_ID from account  where ID =1001; caimao101510           START TRANSACTION;   3     UPDATE account set VACCOUNT_ID='uncommitted' where ID =1001;   4     SELECT VACCOUNT_ID from account  where ID =1001; uncommitted 5 SELECT VACCOUNT_ID from account  where ID =1001; uncommitted     6     ROLLBACK;   7 SELECT VACCOUNT_ID from account  where ID =1001; caimao101510     8 COMMIT;       tx_isolation:SET GLOBAL tx_isolation='read-committed' ID 事务1 事务1输出 事务2 事务2输出 1 START TRANSACTION;       2 SELECT VACCOUNT_ID from account  where ID =1001; caimao101510     3     START TRANSACTION;   4     UPDATE account set VACCOUNT_ID='uncommitted' where ID =1001;   5     SELECT VACCOUNT_ID from account  where ID =1001; uncommitted 6 SELECT VACCOUNT_ID from account  where ID =1001; caimao101510     7     COMMIT;   8 SELECT VACCOUNT_ID from account  where ID =1001; uncommitted     9 COMMIT;       tx_isolation:SET GLOBAL tx_isolation='REPEATABLE-READ' ID 事务1 事务1输出 事务2 事务2输出 1 START TRANSACTION;       2 SELECT VACCOUNT_ID from account  where ID =1001; caimao101510     3     START TRANSACTION;   4     UPDATE account set VACCOUNT_ID='uncommitted' where ID =1001;   5     SELECT VACCOUNT_ID from account  where ID =1001; uncommitted 6 SELECT VACCOUNT_ID from account  where ID =1001; caimao101510     7     COMMIT;   8 SELECT VACCOUNT_ID from account  where ID =1001; caimao101510     9 COMMIT;       tx_isolation:SET GLOBAL tx_isolation='SERIALIZABLE' ID 事务1 事务1输出 事务2 事务2输出 1 START TRANSACTION;       2 SELECT VACCOUNT_ID from account  where ID =1001; caimao101510     3     START TRANSACTION;   4     UPDATE account set VACCOUNT_ID='uncommitted' where ID =1001; STATE: Updating 5 SELECT VACCOUNT_ID from account  where ID =1001; caimao101510           事务2超时   6 COMMIT;       7 START TRANSACTION;       8 UPDATE account set VACCOUNT_ID='uncommitted' where ID =1001;       9     START TRANSACTION;   10     SELECT VACCOUNT_ID from account  where ID =1001; STATE:statistics 11     事务2超时   12 commit;       tx_isolation:SET GLOBAL tx_isolation='REPEATABLE-READ' ID 事务1 事务1输出 事务2 事务2输出 1 START TRANSACTION;       2 select max(ID) FROM account; 124999     3     START TRANSACTION;   4 UPDATE account set gmt_create=date_add(gmt_create,interval +1 day) WHERE ID >=124999;       5     insert into account(VACCOUNT_ID,gmt_create) values(‘eugene',now()); STATE:update 6     事务2超时   7     START TRANSACTION;   8     SELECT * FROM account WHERE ID =124998; 2007-10-20 13:47 9     UPDATE account set gmt_create=date_add(gmt_create,interval +1 day) WHERE ID =124998; 执行成功 10     SELECT * FROM account WHERE ID =124998; 2007-10-21 13:47 11 COMMIT;       12     COMMIT;             1 START TRANSACTION;       2 UPDATE account set gmt_create=date_add(gmt_create,interval -1 day) WHERE gmt_create >'2009-07-01′;       3     START TRANSACTION;   4     SELECT * FROM account WHERE gmt_create>'2009-07-10′ LIMIT 1; 2009-10-2 13:47 5 SELECT * FROM account WHERE gmt_create>'2009-07-10′ LIMIT 1; 2009-10-1 13:47   STATE:update 6     insert into account(VACCOUNT_ID,gmt_create) values(‘gmt_create_test',now());   7     事务2超时   8 COMMIT;       9     SELECT * FROM account WHERE gmt_create>'2009-07-10′ LIMIT 1; 2009-10-1 13:47 无索引条件更新事务 1 START TRANSACTION;         UPDATE account set gmt_create=date_add(gmt_create,interval -1 day) WHERE gmt_create >'2009-07-01′ AND gmt_create

    
 
 

您可能感兴趣的文章:

  • mysql jdbc连接mysql数据库步骤及常见参数详解
  • 深入mysql YEAR() MONTH() DAYOFMONTH()日期函数的详解
  • mysql update语句的用法详解
  • MySql实现跨表查询的方法详解
  • 基于mysql 5.5 设置字符集问题的详解
  • 深入mysql并发插入优化详解
  • 详解MySQL中DROP,TRUNCATE 和DELETE的区别实现mysql从零开始
  • MYSQL 批量替换之replace语法的使用详解
  • 详解MySQL中SlowLog的配置方法(图文)
  • 浅谈SQLServer的ISNULL函数与Mysql的IFNULL函数用法详解
  • 基于mysql数据库的密码问题详解
  • 3步搞定纯真IP数据导入到MySQL的方法详解
  • MySQL Left JOIN时指定NULL列返回特定值详解
  • 深入MYSQL字符数字转换的详解
  • windows环境中mysql忘记root密码的解决方法详解
  • MySQL查询优化之索引的应用详解
  • Linux下MySQL安装配置 MySQL配置参数详解
  • 关于MySQL数据迁移--data目录直接替换注意事项的详解
  • 减少mysql主从数据同步延迟问题的详解
  • Python下的Mysql模块MySQLdb安装详解
  • MySQL数据入库时特殊字符处理详解
  • 解析mysql二进制日志处理事务与非事务性语句的区别
  • MySQL C API中有没有事务处理的函数啊?
  • mysql 事务 回滚 提交
  • 基于mysql事务、视图、存储过程、触发器的应用分析
  • MYSQL事务回滚的2个问题分析
  • 为mysql数据库添加添加事务处理的方法
  • Mysql中的事务是什么如何使用
  • mysql实现事务的提交和回滚实例
  • mysql 锁表锁行语句分享(MySQL事务处理)
  • mysql 事务处理及表锁定深入简析
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • mysql 提示INNODB错误的解决方法
  • MySQL InnoDB和MyISAM数据引擎的差别分析
  • MySQL存储引擎MyISAM与InnoDB的9点区别
  • Mysql启动中 InnoDB: Error: log file ./ib_logfile0 is of different size 0 5242880 bytes 的问题
  • MySQL数据库MyISAM存储引擎转为Innodb的方法
  • 关于mysql中innodb的count优化问题分享
  • 深入探讨:MySQL数据库MyISAM与InnoDB存储引擎的比较
  • mysql 有关“InnoDB Error ib_logfile0 of different size”错误
  • MYSQL无法启动提示: Default storage engine (InnoDB) is not available的解决方法
  • MySQL存储引擎简介及MyISAM和InnoDB的区别
  • mysql之innodb的锁分类介绍
  • mysql5.5与mysq 5.6中禁用innodb引擎的方法
  • MySQL禁用InnoDB引擎的方法
  • MySQL存储引擎 InnoDB与MyISAM的区别
  • 可以改善mysql性能的InnoDB配置参数
  • mysql中engine=innodb和engine=myisam的区别介绍
  • 关于mysql innodb count(*)速度慢的解决办法
  • MySQL不支持InnoDB的解决方法
  • MySQL数据库INNODB表损坏修复处理过程分享
  • Mysql5.5 InnoDB存储引擎配置和优化
  • mysql中如何查看最大连接数(max_connections)和修改最大连接数
  • 在 linux下输入"mysql"命令,进入mysql命令行,但出现“Can't connetc to local MySQL server thuough socket /var/lib/mysql/mysql.sock
  • Mysql查询错误:ERROR:no query specified原因
  • MySQL 重装MySQL后, mysql服务无法启动
  • php安装完成后如何添加mysql扩展
  • 关于mysql innodb count(*)速度慢的解决办法 iis7站长之家
  • mysql中查询当前正在运行的SQL语句并找出mysql中运行慢的sql语句
  • 請教,在redhat linux7.2+mysql 中,系統提示mysql已啟動,網頁卻不能訪問mysql?
  • Myeclipse中自带Tomcat的JDBC连接池配置(mysql和mssql)
  • 求解释: useradd -g mysql mysql -d /home/mysql -s /sbin/nologin
  • MySQL Workbench的下载安装与使用教程


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3