您的位置:首页 > 数据库 > MySQL

7.24 LOCK TABLES/UNLOCK TABLES句法 MySQL不支持事务环境 我靠!!!

2012-05-28 17:30 405 查看
LOCK TABLES tbl_name [AS alias] {READ | [LOW_PRIORITY] WRITE}
[, tbl_name {READ | [LOW_PRIORITY] WRITE} ...]
...
UNLOCK TABLES

LOCK TABLES
为当前线程锁定表。
UNLOCK TABLES
释放被当前线程持有的任何锁。当线程发出另外一个
LOCK TABLES
时,或当服务器的连接被关闭时,当前线程锁定的所有表自动被解锁。

如果一个线程获得在一个表上的一个
READ
锁,该线程(和所有其他线程)只能从表中读。如果一个线程获得一个表上的一个
WRITE
锁,那么只有持锁的线程
READ
WRITE
表,其他线程被阻止。

每个线程等待(没有超时)直到它获得它请求的所有锁。

WRITE
锁通常比
READ
锁有更高的优先级,以确保更改尽快被处理。这意味着,如果一个线程获得
READ
锁,并且然后另外一个线程请求一个
WRITE
锁, 随后的
READ
锁请求将等待直到
WRITE
线程得到了锁并且释放了它。当线程正在等待
WRITE
锁时,你可以使用
LOW_PRIORITY WRITE
允许其他线程获得
READ
锁。如果你肯定终于有个时刻没有线程将有一个
READ
锁,你应该只使用
LOW_PRIORITY
WRITE


当你使用
LOCK TABLES
时,你必须锁定你将使用的所有表!如果你正在一个查询中多次使用一张表(用别名),你必须对每个别名得到一把锁!这条政策保证表锁定不会死锁。

注意你应该锁定任何你正在用
INSERT DELAYED
使用的表,这是因为在这种情况下,
INSERT
被一个不同的线程执行。

通常,你不必锁定表,因为所有单个
UPDATE
语句是原语;没有其他线程能防碍任何其它正在执行SQL语句的线程。当你想锁定表,有一些情况:

如果你将在一堆表上运行许多操作,锁定你将使用的表是较快的。当然缺点是,没有其他线程能更新一个
READ
锁定的表并且没有其他线程能读一个
WRITE
-锁定的表。
MySQL不支持事务环境,所以如果你想要保证在一个
SELECT
和一个
UPDATE
之间没有其他线程到来,你必须使用
LOCK TABLES
。下面显示的例子要求
LOCK TABLES
以便安全地执行:
mysql> LOCK TABLES trans READ, customer WRITE;
mysql> select sum(value) from trans where customer_id= some_id;
mysql> update customer set total_value=sum_from_previous_statement
where customer_id=some_id;
mysql> UNLOCK TABLES;


没有
LOCK TABLES
,另外一个线程可能有一个机会在执行
SELECT
UPDATE
语句之间往
trans
表中插入一个新行。

通过使用渐增更改(
UPDATE customer SET value=value+new_value
)或
LAST_INSERT_ID()
函数,在很多情况下你能使用
LOCK TABLES
来避免。

你也可以使用用户级锁定函数
GET_LOCK()
RELEASE_LOCK()
解决一些情况,这些锁保存在服务器的一张哈希表中并且用
pthread_mutex_lock()
pthread_mutex_unlock()
实现以获得高速度。见7.4.12 其他函数。

有关锁定政策的更多信息,见10.2.8 MySQL 怎样锁定表。

MySQL中所有锁定不会是死锁的。这通过总是在一个查询前立即请求所有必要的锁定并且总是以同样的顺序锁定表来管理。

WRITE
MySQL使用的锁定方法原理如下:

如果在表上没有锁,放一个锁在它上面。
否则,把锁定请求放在写锁定队列中。

READ
MySQL使用的锁定方法原理如下:

如果在表上没有写锁定,把一个读锁定放在它上面。
否则,把锁请求放在读锁定队列中。

当一个锁定被释放时,锁定可被写锁定队列中的线程得到,然后是读锁定队列中的线程。

这意味着,如果你在一个表上有许多更改,
SELECT
语句将等待直到有没有更多的更改。

为了解决在一个表中进行很多
INSERT
SELECT
操作的情况,你可在一张临时表中插入行并且偶尔用来自临时表的记录更新真正的表。

这可用下列代码做到:

mysql> LOCK TABLES real_table WRITE, insert_table WRITE;
mysql> insert into real_table select * from insert_table;
mysql> delete from insert_table;
mysql> UNLOCK TABLES;

如果你在一些特定的情况字下区分检索的优先次序,你可以使用
LOW_PRIORITY
选项的
INSERT
。见7.14
INSERT
句法。

你也能改变在“mysys/thr_lock.c”中的锁代码以使用一个单个队列。在这种情况下,写锁定和读锁定将有同样优先级,它可能帮助一些应用程序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: