应用Mutex通过MySQL InnoDB行锁

时间:2011-05-25 23:46:36

标签: mysql architecture innodb mutex

我的应用程序由几个Apache服务器与一个常见的MySQL盒子进行通信。部分应用程序允许用户在将来创建一小时约会。我需要一种机制来防止不同用户同时来自不同的Apache实例,预订相同的一小时预约时段。我已经看到在Oracle数据库上实现了类似的“系统间互斥”解决方案(基本上是“选择...用于更新”),但还没有处理与MySQL相同的细节。非常感谢任何建议,代码或文档参考,最佳实践等。尝试谷歌,但大多数关于MySQL内部互斥的讨论出现。

这些是我认为相关的我的MySQL设置(我的代码将具有try-catch和all,并且永远不应该保释而不解锁锁定的内容但是必须考虑在这些情况下会发生什么):

mysql> show variables like 'innodb_rollback_on_timeout';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| innodb_rollback_on_timeout | OFF   | 
+----------------------------+-------+
1 row in set (0.00 sec)

mysql> show variables like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 100   | 
+--------------------------+-------+
1 row in set (0.00 sec)

mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 | 
+--------------+
1 row in set (0.00 sec)

您可以推荐任何其他解决方案(在MySQL之外)吗?我确实有一个运行memcached的实例但是经常刷新(并且不确定我是否想要使用memcachedb等来实现容错)。

感谢您的帮助......

2 个答案:

答案 0 :(得分:1)

在这里回答我自己的问题。这种变化是我们最终做的(在PHP中):

<?php
$conn = mysql_connect('localhost', 'name', 'pass');
if (!$conn) {
  echo "Unable to connect to DB: " . mysql_error();
  exit;
 }
if (!mysql_select_db("my_db")) {
  echo "Unable to select mydbname: " . mysql_error();
  exit;
 }
mysql_query('SET AUTOCOMMIT=0'); //very important! this makes FOR UPDATE work                                                                                           
mysql_query('START TRANSACTION');
$sql = "SELECT * from my_mutex_table where entity_id = 'my_mutex_key' FOR UPDATE";
$result = mysql_query($sql);
if (!$result) {
  echo "Could not successfully run query ($sql) from DB: " . mysql_error();
  exit;
 }
if (mysql_num_rows($result) == 0) {
  echo "No rows found, nothing to print so am exiting";
  exit;
 }

echo 'Locked. Hit Enter to unlock...';
$response = trim(fgets(STDIN));
mysql_free_result($result);
echo "Unlocked\n";
?>

验证它可以从两个不同的控制台运行。时间性能比基于标准文件锁的互斥锁稍差,但仍然非常可接受。

答案 1 :(得分:0)

还可以使用MySQL和MariaDB的GET_LOCK(和RELEASE_LOCK)函数:

这些功能可用于实现问题中描述的行为。