来自 pyodbc 查询的最后记录不处理(使用 stomp 的消息传递系统)

Last record from a pyodbc query doesn't process (to messaging system using stomp)

我正在查询一个数据库,其中 returns 38 条记录。在下面的示例中,所有 38 条打印,但最后一条记录没有发送到消息系统,只有前 37 条。我在这里缺少什么???

cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};' + connectionString)
cnxn.autocommit = True
cursor = cnxn.cursor()

sql = (sql statement that returns 38 records)

cursor.execute(sql)
print("Connected")
row = cursor.fetchone()

while row:

    conn = stomp.Connection([('this.that.sys', '61616')])
    conn.connect('user', 'pass', wait=True)
    print("Send " + row.id)  
    conn.send(destination='test1.topic::test1.test1.queue', body=row.payload)

    row = cursor.fetchone()
    conn.disconnect()

这会输出所有 38 个 ID 的列表,但最后一个 Payload 不会发布到队列。

我做了更多测试。这很奇怪。这似乎取决于记录。它们介于 7KB 和 15KB 之间。如果我尝试某两个,只有第一个发布。某三,全部发表。又是某三篇,最后一篇又不发表了

我该如何调试它?

编辑:我做了更多的实验。 Stomp 不保证交货吗?我没有收到任何错误,但有时消息就是没有到达,尤其是最后一条。我稍微重构了我的代码,这似乎有点帮助。我不知道...

cursor.execute(sql)
print("Connected")
row = cursor.fetchone()
print("First " + row.id)
i = 1

try:
    conn = stomp.Connection([('this.that.sys', '61616')])
    conn.connect('user', 'pass', wait=True)
    while row:
        print(str(i))
        print("Send " + row.id + " " + row.status)
        conn.send('test1.topic::test1.test1.queue', row.payload)

        row = cursor.fetchone()
        i = i + 1
    conn.disconnect()
except Exception as e:
    print("Error: %s" % e)

我会改变它:

cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};' + connectionString)
cnxn.autocommit = True
cursor = cnxn.cursor()

sql = (sql statement that returns 38 records)

cursor.execute(sql)
print("Connected")
rows = cursor.fetchall()

for row in rows:

    conn = stomp.Connection([('this.that.sys', '61616')])
    conn.connect('user', 'pass', wait=True)
    print("Send " + row.id)  
    conn.send(destination='test1.topic::test1.test1.queue', body=row.payload)
    conn.disconnect()

send方法是异步执行的吗?如果是这样,那么 disconnect 可能在发送实际发生之前被调用。因此,您可以尝试延迟 disconnect 方法的调用。

还值得注意的是,STOMP 协议支持 receipt header,您可以使用它从代理处获得回复,确保您的 SEND 帧已成功处理。我不是 100% 确定 stomp.py 支持这个,但它应该支持,因为它是协议规范的一部分。

此外,在经纪人身上可能值得 activating trace logging for STOMP。然后您可以准确地看到代理从客户端接收到的内容(例如,如果它过早地接收到 DISCONNECT 帧)。

最后,您绝对不应该为了发送一条消息而连接和断开连接。这是一个众所周知的反模式,应该尽可能避免。你的第二个代码片段在这方面更好。