34.6. 取消进行中的查询

一个客户端应用可以使用本节描述的函数请求取消一个仍在被服务器处理的命令。

PQgetCancel

创建一个数据结构,这个数据结构包含取消一个通过特定数据库连接发出的命令所需要的信息。

PGcancel *PQgetCancel(PGconn *conn);

给出一个PQgetCancel连接对象,PQgetCancel创建一个 PGcancel对象。如果给出 的conn是NULL或者是一个无效的连接,那么它将返回NULL。PGcancel对象是一个不透明的结构, 不应该为应用所直接访问;我们只能把它传递给PQcancel或者PQfreeCancel。 给定一个PGconn连接对象,PQgetCancel创建一个PGcancel对象。如果给定的connNULL或者一个不合法的连接,它将返回NULLPGcancel对象是一个透明的结构,它不能直接被应用访问。它只能被传递给PQcancelPQfreeCancel

PQfreeCancel

释放一个由PQgetCancel创建的数据结构。

void PQfreeCancel(PGcancel *cancel);

PQfreeCancel释放一个由前面的PQgetCancel创建的数据对象。 PQfreeCancel释放一个之前由PQgetCancel创建的数据对象。

PQcancel

要求服务器放弃当前命令的处理。

int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize);

如果取消请求成功发送,则返回值为 1,否则为 0。如果不成功,则errbuf会被填充一个解释性的错误消息。errbuf必须是一个尺寸为errbufsize的字符数组(推荐尺寸为 256 字节)。,解释为何不成功。errbuf必须是 一个大小为errbufsize的 char 数组(建议大小为 256 字节)。

不过,成功的发送并不保证请求会有任何效果。如果取消有效,那么当前的命令将提前终止并且返回一个错误结果。如果取消失败(也就是说, 因为服务器已经完成命令的处理),那么就根本不会有可见的结果。

如果PQcancel是信号句柄里的一个局部变量,那么PQcancel可以在一个信号 句柄里安全地调用。在PQcancel涉及的范围里,PQcancel对象都是只读的, 因此我们也可以从一个与处理PGconn对象的线程分离的线程里处理它。 如果errbuf是信号处理器中的一个局部变量,PQcancel可以从一个信号处理器中安全地调用。在PGcancel有关的范围内,PQcancel都是只读的,因此也可以在一个从操纵PGconn对象的线程中独立出来的线程中调用它。

PQrequestCancel

PQrequestCancelPQcancel的一个被废弃的变体。

int PQrequestCancel(PGconn *conn);

要求服务器放弃当前命令的处理。它直接在PGconn对象上进行操作, 并且如果失败,就会在PGconn对象里存储错误消息(因此可以用PQerrorMessage检索出来)。 尽管功能相同,这个方法在多线程程序里和信号处理器里会带来危险,因为它可能 覆盖PGconn的错误消息,进而将当前连接上正在处理的操作搞乱。