2010-07-28 62 views
10

什么是MySQL(或任何RDBMS)中的锁定以及何时使用它?带一个例子的外行人解释会很棒!什么是MySQL中的锁定以及何时使用它?

+0

这对于并发用户是一个有用的优化:http://www.devshed.com/c/a/MySQL/MySQL-Optimization-part-2/ – 2010-07-28 14:04:38

+0

我认为你应该接受@Chris的答案。 – ripper234 2010-11-30 20:34:17

回答

9

我们有200 $

我去ATM,把我的卡插入机器时,机器会检查我的$ 200

的平衡。同时,你去一个平衡的合资银行账户进入银行并要求50美元,出纳员开着你的账户并确认你有钱。

我要求的$ 200提款,机器计算我的钱给我200 $,并设置我的余额$ 0

柜员计算你的钱,给你$ 50,系统然后更新的帐户余额150美元(200美元--50美元撤销)。

所以现在我们有250美元的现金和150美元的账户。 200美元的利润。

数据库应该使用锁来防止两个事务同时发生。

问题是如果您以这种方式处理每个事务,那么我们将失去并发性并且性能会受到影响,因此根据场景使用不同的transaction isolation levels,例如,您可能不在意某人可以修改数据已在交易中阅读。

http://en.wikipedia.org/wiki/Isolation_%28database_systems%29

你应该学会这些,并了解他们是适用的场景。

+0

谢谢@Chris Diver很好的解释!我现在明白了;-) – Imran 2010-07-28 16:46:41

3

前几天我回答a question on SO,给这表明的情况下locking允许多个用户同时插入表中的行和递增id,而无需使用AUTO_INCREMENT一个例子。

考虑以下方案为例:

CREATE TABLE demo_table (id int) ENGINE=INNODB; 

-- // Add few rows 
INSERT INTO demo_table VALUES (1), (2), (3); 

然后我们可以做到以下几点:

START TRANSACTION; 

-- // Get the MAX(id) so that we increment it by one 
SELECT @x := MAX(id) FROM your_table FOR UPDATE; 

+---------------+ 
| @x := MAX(id) | 
+---------------+ 
|    3 | 
+---------------+ 
1 row in set (0.00 sec) 

FOR UPDATE语法是什么其实是把对这个查询读取行上的锁。

没有提交事务,我们开始另一个单独的会话(模拟并发用户),并执行相同的:

START TRANSACTION; 

-- // Get the MAX(id) as well 
SELECT MAX(id) FROM demo_table FOR UPDATE; 

数据库将等到锁前一交易日设置运行此之前发布查询。

因此切换到上届会议上,我们可以插入新行并提交事务:

-- // Insert a new row with id = MAX(id) + 1 
INSERT INTO demo_table VALUES (@x + 1); 

COMMIT; 

后的第一届会议提交事务,锁将被解除,并在第二届查询返回:

+---------+ 
| MAX(id) | 
+---------+ 
|  4 | 
+---------+ 
1 row in set (8.19 sec) 

注意,如果没有锁定,第二届会议会立即返回,但3作为MAX(id)而不是4。如果两个会话都插入一行idMAX(id) + 1,则两者都会插入id = 4。您可以在没有FOR UPDATE位的情况下模拟相同的测试,看看如何在没有锁的情况下处理这个问题。

6

锁定对于避免两个用户同时修改数据至关重要。您可能认为这不太可能,但根据应用程序的不同,如果相同的数据经常被不同的用户更改,则存在重大风险。

想象一下以下情况使用锁:约翰打开了他的屏幕(他不知道他用的数据库,他只是谁在看一个漂亮的屏幕终端用户),修改一些数据,然后点击“保存”。假设John在9:30开启屏幕,然后在9:32保存数据。

但是,玛丽在9:29开了完全相同的屏幕和相同的记录。那时她看到约翰在9点30分做过的数据。然后,她更新记录,并在9:31点击“保存”。

什么数据被保存?约翰的还是玛丽的?

玛丽高兴地继续研究其他记录,当她回来后再次打开记录时,她发现她的变化已经消失,她看到了约翰的变化!

请注意,锁定必须明智地使用,以防止出现意想不到的副作用。例如,假设您的程序在每次打开它进行更改时锁定记录。如果约翰锁定记录,并且让他的会话屏幕打开吃午饭或他失去联系,会发生什么?锁可以长时间保持在那里,锁定和不可更改,同时禁止其他人更改(甚至查看)该记录。其他考虑因素可能是性能,因为数据库锁定和解锁记录的时间可能对于大量事务变得明显。

理解锁定对维护用户和数据的完整性至关重要。请看文档。

+0

感谢@luiscolorado这真的有所帮助:-) – Imran 2010-07-28 16:47:54

+0

版本化数据将是您描述的用例的更好解决方案。你无法真正保持这么长时间的锁定......我要做的是,当John保存时,阅读data +版本,将它们与你显示的用户进行比较,然后对检查数据执行UPDATE对于你刚刚在两分钟前阅读的版本。如果版本不一样,这意味着其他人触摸了您的数据 - 您必须刷新它。 – ripper234 2010-11-30 20:33:34

+2

@ ripper234:这就是为什么我说锁定需要多种考虑才能达到最佳方法。你解释的情况是正确的,你的建议很好。我不打算也不可能在这里对这个概念进行完整的讨论。目的是提供一个简单的,外行的答案。 – luiscolorado 2012-02-08 12:03:07

相关问题