如何在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");
解决方案
回答
我们可以在其他线程中执行阻塞查询,而永远不会被超时困扰。当一些数据到达时,我们通知需要了解事务状态的线程。
回答
如果我是从头开始写的,那我会做的,但这是一个服务器应用程序,我们只是在升级而不是进行大量返工。
回答
与其尝试使用表锁伪造交易,不如切换到获得实际交易的innodb表?只要确保将默认事务隔离级别设置为REPEATABLE READ。
回答
正如我所说,在生产系统中进行实时转换或者重新架构并不是一件容易的事。我对MySQL没有提供检查锁的方法或者选择不挂起等待锁的方法感到有些沮丧。
回答
我不知道这在资源使用,"最佳实践"和"整洁度"以及所有其他方面是否是一个好主意……但是我们现在已经从重新架构角度反复描述了束缚手铐"干净"的系统...就这样...
我们能否仅为了发送LOCK语句而打开一个新的单独连接?然后在收到超时警报时关闭该连接?通过关闭/销毁专用于LOCK语句的连接,这会不会在本质上"取消" LOCK语句?我不确定是否会像我所描述/猜测的那样发生这样的事件,但是也许这是可以测试的东西。
回答
到目前为止,我所描述的经验向我表明,关闭其中正在运行查询的连接会导致seg错误。因此,将查询分派到另一个连接中并没有太大帮助,因为这也会导致错误。
回答
我们可以通过以下方式实现"取消类"行为:
我们可以在单独的线程上执行查询,无论是否发生超时,该线程都会继续运行。超时发生在主线程上,并将变量设置为" 1"以表示它已发生。然后,我们可以在主线程上做任何我们想做的事情。
查询完成后,查询线程将检查是否已发生超时。如果没有,它将完成所需的其余工作。如果有的话,它只是解锁它刚刚锁定的表。
我知道这听起来有点浪费,但是锁定-解锁时间段基本上应该是瞬时的,并且我们将尽可能接近所需的结果。