mysql 锁表 for update 引擎/事务

转载 2016年06月02日 08:44:20

转载:http://www.cnblogs.com/bigfish--/archive/2012/02/18/2356886.html

因为之前用过oracle,知道利用select * for update 可以锁表。所以很自然就想到在mysql中能不能适应for update来锁表呢。

学习参考如下

 由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例) ,否则MySQL将会执行Table Lock (将整个资料表单给锁住)。 
举个例子: 
假设有个表单products ,里面有id跟name二个栏位,id是主键。 
例1: (明确指定主键,并且有此笔资料,row lock) 
SELECT * FROM products WHERE id='3' FOR UPDATE; 
例2: (明确指定主键,若查无此笔资料,无lock) 
SELECT * FROM products WHERE id='-1' FOR UPDATE; 
例2: (无主键,table lock) 
SELECT * FROM products WHERE name='Mouse' FOR UPDATE; 
例3: (主键不明确,table lock) 
SELECT * FROM products WHERE id<>&apos;3&apos; FOR UPDATE; 
例4: (主键不明确,table lock) 
SELECT * FROM products WHERE id LIKE &apos;3&apos; FOR UPDATE; 
注1: FOR UPDATE仅适用于InnoDB,且必须在交易区块(BEGIN/COMMIT)中才能生效。 
注2: 要测试锁定的状况,可以利用MySQL的Command Mode ,开二个视窗来做测试。

由上面的InnoDB 已经交易区块引出两个问题。

1. what is InnoDB?

 MySQL是我们比较常用的一种数据库软件。它有着诸多的优点,如开源的,免费的等等。其实它还有一个很好的特点,那就是有多种引擎可以供你选择。如果赛车手能根据不同的路况,地形随手更换与之最适宜的引擎,那么他们将创造奇迹。然而目前他们还做不到那样便捷的更换引擎,但是我们却可以! 
     所谓知己知彼方可百战不殆,要想将它们发挥到极致,首先我们应该来认识一下MySQL提供给我们的这几种引擎。
     一般来说,MySQL有以下几种引擎:ISAM、MyISAM、HEAP、InnoDB和Berkley(BDB)。注意:不同的版本支持的引擎是有差异的。

进一步:

如何查看MySQL的当前存储引擎?

一般情况下,mysql会默认提供多种存储引擎,你可以通过下面的查看:

看你的mysql现在已提供什么存储引擎:
mysql> show engines;

以上说明我的mysql默认使用的InnoDB引擎,并且支持MyISAM,memory,archive,Mrg_myisam。

 后面还跟着解释, InnoDB 的解释是:支持事务,行级别锁定,外键。

看你的mysql当前默认的存储引擎:
mysql> show variables like &apos;%storage_engine%&apos;;

 

你要看某个表用了什么引擎(在显示结果里参数engine后面的就表示该表当前用的存储引擎):
mysql> show create table 表名;

实这是一定的,因为我的mysql引擎就是InnoDB,默认情况下创建的表当前也是以InnoDB为引擎的喽

2. what is 交易区块?

 参考:http://hi.baidu.com/cuihu0706/blog/item/1dd6ccb1621c355709230278.html

事务处理在各种管理系统中都有着广泛的应用,比如人员管理系统,很多同步数据库操作大都需要用到事务处理。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
删除的SQL语句
delete from userinfo where ~~~
delete from mail where ~~
delete from article where~~
~~
   如果没有事务处理,在你删除的过程中,假设出错了,只执行了第一句,那么其后果是难以想象的!
但用事务处理。如果删除出错,你只要rollback就可以取消删除操作(其实是只要你没有commit你就没有确实的执行该删除操作)   一般来说,在商务级的应用中,都必须考虑事务处理的!

MYSQL数据库从4.1就开始支持事务功能,据说5.0将引入存储过程^_^
      先简单介绍一下事务吧!事务是DBMS得执行单位。它由有限得数据库操作序列组成得。但不是任意得数据库操作序列都能成为事务。一般来说,事务是必须满足4个条件(ACID)
      原子性(Autmic):事务在执行性,要做到“要么不做,要么全做!”,就是说不允许事务部分得执行。即使因为故障而使事务不能完成,在rollback时也要消除对数据库得影响!
     一致性(Consistency):事务得操作应该使使数据库从一个一致状态转变倒另一个一致得状态!就拿网上购物来说吧,你只有即让商品出库,又让商品进入顾客得购物篮才能构成事务!
     隔离性(Isolation):如果多个事务并发执行,应象各个事务独立执行一样!
     持久性(Durability):一个成功执行得事务对数据库得作用是持久得,即使数据库应故障出错,也应该能够恢复!

   MYSQL的事务处理主要有两种方法。
   1、用begin,rollback,commit来实现
        begin 开始一个事务
        rollback 事务回滚
        commit  事务确认
    2、直接用set来改变mysql的自动提交模式
       MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过
      set autocommit=0   禁止自动提交
      set autocommit=1 开启自动提交
但注意当你用 set autocommit=0 的时候,你以后所有的SQL都将做为事务处理,直到你用commit确认或rollback结束,注意当你结束这个事务的同时也开启了个新的事务!按第一种方法只将当前的作为一个事务!个人推荐使用第一种方法!
MYSQL中只有INNODB和BDB类型的数据表才能支持事务处理!其他的类型是不支持的!(切记!)

 MYSQL5.0 WINXP下测试通过~   ^_^

mysql> use test;
Database changed
mysql> CREATE TABLE `dbtest`(
     -> id int(4)
     -> ) 
TYPE=INNODB;
Query OK, 0 rows affected, 1 warning (0.05 sec)

mysql> select * from dbtest
     -> ;
Empty set (0.01 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into dbtest value(5);
Query OK, 1 row affected (0.00 sec)

mysql> insert into dbtest value(6);
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from dbtest;
+------+
| id    |
+------+
|     5 |
|     6 |
+------+
2 rows in set (0.00 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into dbtest values(7);
Query OK, 1 row affected (0.00 sec)

mysql> rollback;   //这里回滚了
Query OK, 0 rows affected (0.00 sec)

mysql> select * from dbtest;
+------+
| id    |
+------+
|     5 |
|     6 |
+------+
2 rows in set (0.00 sec)

mysql>

 

 

既然已经知道了相关的知识,那么下面就用for update来锁定行,进行试验

以上例中student表为例,

 1. 使用begin开始一个事务

 2. 利用select * for update 锁定行,

 3. 在新窗口中验证非选中行是否被锁定 ----未被锁定

 4. 在新窗口中验证选中行是否被锁定  -----锁定,update语句在等待了一段时间后失败。


Mysql 锁表 for update (引擎/事务)

http://www.cnblogs.com/bigfish--/archive/2012/02/18/2356886.html 因为之前用过oracle,知道利用select * for up...
  • lcathm
  • lcathm
  • 2014年04月05日 18:53
  • 453

并发控制 mysql InnoDB锁表,事务及处理方法

InnoDB锁问题 InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION);二是采用了行级锁。行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题。下面...
  • aggrelxf
  • aggrelxf
  • 2015年02月28日 15:54
  • 3734

mysql(五)forupdate语句锁表的细节

我们都知道for update语句会锁住一张表,锁表的细节很多人却不太清楚,下面我们举例看下。 在表上我们有个索引,如下: 现在在我们通过索引store_id锁表: 我们再开一个客户端,还是锁住同一个...
  • lz710117239
  • lz710117239
  • 2017年05月12日 20:33
  • 1858

【电商网站】mysql中select * for update锁表的问题

先前介绍过SELECT ... FOR UPDATE的用法,不过锁定(Lock)的资料是判别就得要注意一下了。由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL...
  • yanhui_wei
  • yanhui_wei
  • 2013年02月18日 11:41
  • 2277

mysql的插表以及更新操作导致的死锁问题

一.mysql的死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。 表级锁不会产生死锁.所以解决死锁主要还是针对于最常用的Inno...
  • alexander_zhou
  • alexander_zhou
  • 2015年10月18日 21:32
  • 5138

MySqL 事务与锁的深入学习笔记

之前学习MySql的简单使用的时候.学习了事务的概念,事务的隔离级别,以及何时使用事务,怎么使用事务等等比较简单的东西。最近不停的在想数据库内部是如何实时事务的,如何避免脏数据的。数据库内部是否有与并...
  • canot
  • canot
  • 2016年12月22日 15:33
  • 2442

mysql innodb update 锁表

MySQL的innodb存储引擎支持行级锁,innodb的行锁是通过给索引项加锁实现的,这就意味着只有通过索引条件检索数据时,innodb才使用行锁,否则使用表锁。...
  • u013960139
  • u013960139
  • 2017年06月08日 15:57
  • 256

mysql查询更新时的锁表机制分析(只介绍了MYISAM)

为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制。 一、概述 MySQL有三种锁的级别:页级、表级、行级。 MyISAM和MEMORY存储引擎采...
  • u010942020
  • u010942020
  • 2016年07月16日 18:16
  • 2046

MySQL数据更新中断后事务锁定

问题:数据在更新的时候强制停止后,再次操作报异常:Lock wait timeout exceeded; try restarting transaction 问题描述: ### Erro...
  • FanJizhi
  • FanJizhi
  • 2017年06月15日 15:26
  • 317

MySQL 高性能存储引擎:TokuDB初探

转载来自标点符的《MySQL 高性能存储引擎:TokuDB初探》 https://www.biaodianfu.com/tokudb.html 在安装MariaDB的时候了解到...
  • zdy0_2004
  • zdy0_2004
  • 2016年12月19日 22:31
  • 1395
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:mysql 锁表 for update 引擎/事务
举报原因:
原因补充:

(最多只允许输入30个字)