如何在c ++中超时mysql ++查询

时间:2008-09-17 10:02:24

标签: c++ mysql

我使用mysql ++来连接MySQL数据库以执行一堆数据查询。由于我正在读取的表格经常被写入,并且我需要一致的数据视图,因此我首先锁定表格。但是,MySQL在其锁定查询中没有'NOWAIT'的概念,因此如果表被其他东西锁定,使它们长时间锁定,我的应用程序就在那里等待。我想要它做的是能够返回并说出“无法获得锁定”之类的东西,并在几秒钟后重试。我对此超时的一般尝试如下。

如果我在锁定数据库上的表后运行它,我会收到超时命中的消息,但我不知道如何让mysql_query行终止。我很感激任何帮助/想法!


volatile sig_atomic_t success = 1;

void catch_alarm(int sig) {
        cout << "Timeout reached" << endl;
        success = 0;
        signal(sig,catch_alarm);
}

// connect to db etc.
// *SNIP

signal (SIGALRM, catch_alarm);
alarm(2);
mysql_query(p_connection,"LOCK TABLES XYZ as write");

7 个答案:

答案 0 :(得分:3)

您可以通过这种方式实现“取消”行为:

您在单独的线程上执行查询,无论是否发生超时,该线程都会继续运行。超时发生在主线程上,并将变量设置为“1”,表示它已发生。然后你在主线程上做任何你想做的事情。

查询完成后,查询线程会检查是否已发生超时。如果没有,它将完成它需要做的其余工作。如果它有,它只是解锁它刚刚锁定的表。

我知道这听起来有点浪费,但锁定解锁期应基本上是即时的,你可以尽可能接近你想要的结果。

答案 1 :(得分:0)

您可以在不同的线程中执行阻塞查询,并且永远不会被超时困扰。当一些数据到达时,您通知需要了解交易状态的线程。

答案 2 :(得分:0)

如果我是从头开始编写的话,我会这样做,但这是一个服务器应用程序,我们只是在升级而不是大量的返工。

答案 3 :(得分:0)

而不是试图伪造带有表锁的事务,为什么不切换到你获得实际事务的innodb表?只需确保将默认事务隔离级别设置为REPEATABLE READ。

答案 4 :(得分:0)

正如我所说,在生产系统中这是一个现场的“切换”或重新设计并不容易。我有点沮丧的是,MySQL没有提供检查锁的方法,也没有选择不挂机等待。

答案 5 :(得分:0)

我不知道这在资源使用和“最佳实践”和“清洁度”方面是否是一个好主意,以及所有其他...但你现在已经反复描述了绑定你的手铐 - 建立一个“干净”的系统......所以这里...... [/ p>

您是否可以仅为发送LOCK语句打开一个新的单独连接?捕获超时警报时关闭该连接?通过关闭/破坏专用于LOCK语句的连接,这本质上不会“取消”LOCK语句吗?我不确定这些事件是否会像我所描述/猜到的那样发生,但也许是值得测试的。

答案 6 :(得分:0)

到目前为止我所描述的经验告诉我,关闭运行查询的连接会导致seg错误。因此,将该查询分派到不同的连接中确实没有用,因为这也会导致错误。