1

在我的应用程序中,我希望在请求写入一些数据时立即执行对数据库的任何插入。

我正在使用 InnoDB 引擎。

由于插入需要排他锁,因此当当前读取查询具有共享锁时,可能会出现一些其他读取再次具有共享锁,并且写入操作可能需要等待很长时间。

我希望当队列中有写操作时,没有读操作获得共享锁。一旦在当前写请求之前启动的读取完成,就应该执行写操作。之后,应该进行所有其他读取操作。

如何实施?

编辑

由于我使用的是 InnoDB 表并且我没有实现表锁,所以 select 和 insert 之间不应该有冲突。这将是选择和更新。(如果选择和插入之间也存在冲突,请纠正我)

在 MySQL 中,update 的优先级高于 select。但是如果有一些读取查询正在执行,那么更新查询就会出现,然后是一些读取查询。在这种情况下,更新后的读取查询是否会等待更新完成,如此处所述http://dev.mysql.com/doc/refman/5.0/en//table-locking.html或者他们将获得共享锁以及在更新查询被触发之前存在的读取查询?

4

2 回答 2

1

从数据库读取时不需要获取共享锁。事实上,使用默认事务隔离级别REPEATABLE READ一个事务内的普通SELECT查询从一致的快照中读取。没有获取和需要锁,在这个事务中,您根本不会看到其他事务中提交的任何更改。

由于没有获取共享锁,用于更新查询的排他锁会立即按照提交顺序授予其他会话。

MySQL 文档说以下

一致读取是 InnoDB 在 READ COMMITTED 和 REPEATABLE READ 隔离级别处理 SELECT 语句的默认模式。一致读取不会对其访问的表设置任何锁定,因此其他会话可以在对表执行一致读取的同时自由修改这些表。

假设您在默认的 REPEATABLE READ 隔离级别下运行。当您发出一致读取(即普通的 SELECT 语句)时,InnoDB 会为您的事务提供一个时间点,根据该时间点您的查询会看到数据库。如果另一个事务在分配您的时间点后删除了一行并提交,您不会看到该行已被删除。插入和更新的处理方式类似。

于 2013-01-02T11:28:32.450 回答
0

您可以尝试查看INSERT DELAYED Mysql Insert Delayed

不幸的是,它在 innodb 上不可用。

PS:如果表上已经存在共享锁,则无法获取排他锁。所以基本上,在你的情况下:3次读取获得一个共享锁,一次插入需要排他锁。只有在选择完成后,插入才能获得锁。

于 2012-12-31T11:45:43.600 回答