`
solitary
  • 浏览: 73461 次
社区版块
存档分类
最新评论

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

阅读更多

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

 

Mysql 锁表 for update (引擎/事务)
因为之前用过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锁类型以及子查询锁表问题、解锁1

    FOR UPDATE`语句就是一种行级锁的用法,用于在更新数据前锁定选定的行,防止其他事务在此期间对这些行进行修改。当在查询条件中明确指定了主键,并且查询能够匹配到具体行时,InnoDB会实施行锁。例如: ```sql ...

    mysql事务select for update及数据的一致性处理讲解

    如果不使用事务和`FOR UPDATE`,可能存在如下风险:在`SELECT`之后到`UPDATE`之前,其他事务可能已经将库存减少到0,但我们的事务仍然错误地更新了数量。为了解决这个问题,可以使用如下事务: 1. `SET AUTOCOMMIT=...

    Mysql 数据库死锁过程分析(select for update)

    避免这种死锁的一种方法是在设计事务时遵循一定的顺序规则,例如,确保所有事务按照相同的顺序访问和修改数据,或者使用`FOR UPDATE SKIP LOCKED`(Oracle支持,但MySQL不直接支持)来跳过已锁定的行。另外,可以...

    mysql事务与锁机制(存储引擎和锁、MyISAM锁机制、InnoDB锁机制、Next-Key锁、Dead-Lock).docx

    ### MySQL事务与锁机制详解 #### 一、锁概念简介 **1、基础描述** 锁机制主要用于解决数据库中多线程或多个会话同时访问同一数据资源时出现的竞争问题。在MySQL中,锁机制是非常重要的组成部分之一,它与其他核心...

    MySQL悲观锁总结和实践

    MySQL的InnoDB存储引擎支持多种类型的锁,其中最常用的就是悲观锁的实现方式之一——行级锁。下面我们将通过一个具体的例子来详细解释如何在MySQL中使用悲观锁。 #### 三、示例场景分析 假设有一个商品表`t_goods`...

    MySQL:锁机制.pdf

    - InnoDB与MyISAM存储引擎的区别:InnoDB支持行级锁和事务,而MyISAM主要支持表级锁。 在使用过程中,应该根据实际的应用场景和性能需求,合理选择存储引擎和锁策略,以达到最优的并发控制效果。对于可能出现的锁争...

    MySQL 全局锁、表级锁、行级锁

    FOR UPDATE` 或 `UPDATE/DELETE`)则会阻止其他事务读取和写入该表,直到锁被释放。 - 表级锁的优缺点:锁定粒度大,导致锁冲突的可能性较高,但锁定和解锁速度快,适合于锁定操作较少、数据争用不激烈的情况。 3...

    行业-59 对MySQL锁机制再深入一步,共享锁和独占锁到底是什么?l.rar

    MySQL的InnoDB存储引擎支持行级锁定,这极大地提高了并发性能,因为相比于表级锁,行级锁只锁定涉及的数据行,而不是整个表。 死锁是锁机制可能导致的问题之一。当两个或更多事务相互等待对方释放锁时,就会发生...

    mysql 锁表锁行语句分享(MySQL事务处理)

    FOR UPDATE`语句选择了表`prizes`中id为特定值的行,并将其锁定,这样其他事务就无法同时读取或修改这一行。然后,执行`DELETE`语句删除了锁定的行。最后,通过`commit`提交事务,确保所有更改被永久保存。 MySQL...

    mysql_innoDB 事务与锁详解

    FOR UPDATE`时,会话事务中查找的数据将被加上排他锁,其他会话将无法再对该数据加任何类型的锁,直到当前事务结束。 3. **插入、更新和删除操作**:当使用`INSERT`、`UPDATE`或`DELETE`时,会话事务会对数据加上...

    (mysql面试题)MySQL中的事务和锁的概念及其作用及代码展示.txt

    3. **更新操作**:使用`UPDATE`语句将`id`为1的学生年龄改为20,并通过`FOR UPDATE`关键字指明使用排他锁,确保在事务执行期间没有其他事务可以修改该记录。 4. **提交事务**:使用`COMMIT`命令来提交事务,将所有...

    Mysql 锁机制的详细说明

    MySQL 的锁机制是数据库管理系统中用于协调多个并发事务对数据进行访问的一种机制,确保数据的一致性和完整性。在开发中,虽然我们可能并不总是主动使用锁,但它们在多用户环境下确保数据正确性的关键。数据库在某些...

    mysql SELECT FOR UPDATE语句使用示例

    MySQL中的`SELECT FOR UPDATE`语句是在事务处理中用于实现数据锁定的一种机制,它主要用于解决多用户并发操作时的数据一致性问题。在InnoDB存储引擎下,MySQL默认的事务隔离级别是`REPEATABLE READ`,这允许事务在...

    MySQL与Java锁的学习

    FOR UPDATE`语句实现悲观锁。 3. **显式锁**:Java可以调用`Statement.setLockTimeout()`方法设置锁等待时间,或者使用`SELECT ... LOCK IN SHARE MODE`获取共享锁。 4. **事务隔离级别**:Java可以通过设置`...

    分布式锁实现(基于redis-mysql)1

    FOR UPDATE`)和乐观锁。悲观锁在事务开始时立即锁定资源,直到事务结束才释放,而乐观锁则在更新数据时检查是否有其他事务已经修改了数据。具体实现方式取决于业务需求和性能考虑。 **基于Zookeeper实现分布式锁*...

Global site tag (gtag.js) - Google Analytics