如何在C ++中使mysql ++查询超时

时间:2020-03-05 18:58:28  来源:igfitidea点击:

我正在使用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");

解决方案

回答

我们可以在其他线程中执行阻塞查询,而永远不会被超时困扰。当一些数据到达时,我们通知需要了解事务状态的线程。

回答

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

回答

与其尝试使用表锁伪造交易,不如切换到获得实际交易的innodb表?只要确保将默认事务隔离级别设置为REPEATABLE READ。

回答

正如我所说,在生产系统中进行实时转换或者重新架构并不是一件容易的事。我对MySQL没有提供检查锁的方法或者选择不挂起等待锁的方法感到有些沮丧。

回答

我不知道这在资源使用,"最佳实践"和"整洁度"以及所有其他方面是否是一个好主意……但是我们现在已经从重新架构角度反复描述了束缚手铐"干净"的系统...就这样...

我们能否仅为了发送LOCK语句而打开一个新的单独连接?然后在收到超时警报时关闭该连接?通过关闭/销毁专用于LOCK语句的连接,这会不会在本质上"取消" LOCK语句?我不确定是否会像我所描述/猜测的那样发生这样的事件,但是也许这是可以测试的东西。

回答

到目前为止,我所描述的经验向我表明,关闭其中正在运行查询的连接会导致seg错误。因此,将查询分派到另一个连接中并没有太大帮助,因为这也会导致错误。

回答

我们可以通过以下方式实现"取消类"行为:

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

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

我知道这听起来有点浪费,但是锁定-解锁时间段基本上应该是瞬时的,并且我们将尽可能接近所需的结果。