Javascript Postgresql。一个进程插入,第二个进程尝试选择但未找到

Javascript Postgresql。一个进程插入,第二个进程尝试选择但未找到,javascript,postgresql,tomcat,Javascript,Postgresql,Tomcat,奇怪的情况 我尝试启动聊天应用程序。 我使用postgresql 9.3和tomcat作为web服务器 当一个浏览器向另一个浏览器发送消息时会发生什么情况: 1-向服务器发送消息(tomcat) 2-Tomcat将msg放入数据库并获取其id INSERT INTO messages VALUES('first message') returning into MSGID id 3-Tomcat将消息重新发送到浏览器B(websocket收件人) 4-浏览器B发送系统回答:MSGID_已读取

奇怪的情况

我尝试启动聊天应用程序。 我使用postgresql 9.3和tomcat作为web服务器

当一个浏览器向另一个浏览器发送消息时会发生什么情况:

1-向服务器发送消息(tomcat)

2-Tomcat将msg放入数据库并获取其id

INSERT INTO messages VALUES('first message') returning into MSGID id
3-Tomcat将消息重新发送到浏览器B(websocket收件人)

4-浏览器B发送系统回答:MSGID_已读取

5-Tomcat更新数据库消息

UPDATE messages SET readtime = now() WHERE id = MSGID
所有的工作,但有时在第5点更新无法找到MSGID的消息

非常奇怪,因为在第2点我得到了消息记录ID,但在第5点,没有

postgresql是否可以缓慢写入,并且此记录不允许(不可见)来自并行数据库连接

更新

我找到了解决方案,只需将insert放在begin/exception/end块中

BEGIN
    INSERT INTO messages (...)
        VALUES (...)
        RETURNING id INTO MSGID;
EXCEPTION
    WHEN unique_violation THEN
     -- nothing
END;
更新2

详细地说,使用BEGIN块测试上述更改不会产生任何影响。 Javascript解决方案!我从其他线程发送了websocket消息,问题解决了

// WebSocket send message function
// Part of code. so is a web socket
send = function(msg) {
    if (msg != null && msg != '') {
        var f = function() {
            var mm = m;
//            JCC.log('SENT: [' + mm + ']');
            so.send(mm);
        };
        setTimeout(f, 1);
    }
};

好的,问题是,通常情况下,编写器不会阻止读卡器。这意味着第一次插入发生,第二次插入在第一次提交之前触发。这会在应用程序中引入竞争条件,从而导致您看到的问题

这里最好的问题是切换到可序列化快照隔离,或者执行您已经完成的操作,并在插入时执行异常处理。这样或那样,您最终必须处理额外的异常处理(如果可序列化,则有时可能会发生序列化失败异常,您可能需要等待)


在您的情况下,尽管plpgsql中的异常处理会对性能造成影响,但最好按照当前的方式进行操作,因为这样可以避免锁定问题并等待事务完成。

是未提交事务中的步骤1和步骤2,因此,在提交第一个事务之前,步骤5无法查看结果?检查tomcat等中的“自动提交”设置。在资源jndi池上尝试了defaultAutoCommit=“true”-没有任何变化,您是对的,事务延迟了。我在阅读答案前插入延迟一秒,现在一切正常!您可能面临写入倾斜。检查。一种解决方案是实现重试处理程序。