Express.js 不断返回数据库中不再存在的旧查询结果

Express.js keeps returning old query results that no longer exist in the database

提问人:dovexz12323 提问时间:11/13/2023 最后编辑:Brian Tompsett - 汤莱恩dovexz12323 更新时间:11/20/2023 访问量:169

问:

我正在将PostgreSQL与Express.js一起使用

我遇到了一个问题,当我用新条目更新我的数据库并删除旧条目时,无论如何,它都会只返回旧条目(几天前已经删除了),就好像它正在使用缓存一样。

我试过了:

设置标题 -res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, private');

重新启动数据库本身,并在 PostgreSQL 上使用;VACUUM ANALYZE

这是我与数据库的连接:

const { Pool } = require('pg');
const { dbConfig, sshConfig } = require('./database_config');

const dbPool = new Pool(dbConfig);

const connectToDatabase = () => {
    dbPool.connect((error) => {
        if (error) throw error;
    });
};

module.exports = { dbPool, connectToDatabase };

这是我的端点之一。

//I connect to the database in index.js
connectToDatabase();


app.get('/getEntries', async (req, res) => {
    try {
        const query = 'SELECT * FROM listings';

        const result = await dbPool.query(query);
        res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, private');

        res.json(result.rows);
    } catch (error) {
        console.error('Error fetching data:', error);
        res.status(500).send('Error fetching data');
    }
});

它不断返回旧数据,不久前从数据库中删除,如何解决这个问题?

JavaScript 节点 .js PostgreSQL Express

评论

2赞 prasad_ 11/13/2023
您可能希望验证是否始终连接和使用(删除和查询)同一数据库。
1赞 dovexz12323 11/13/2023
@prasad_我确实连接到该数据库,通过终端检查连接,使用相同的凭据,数据库查询新结果,而后端返回旧结果。除了初始数据库之外,也没有其他现有数据库。
0赞 rveerd 11/16/2023
您是否在 Express 中记录请求,例如使用 Morgan?您是否看到 Express 服务器实际处理了请求?
0赞 Salman A 11/16/2023
如果重新启动pgsql,问题会消失吗?重新启动应用程序后问题会消失吗?如果直接查询pgsql数据库,是否还能看到已删除的行?
0赞 dovexz12323 11/17/2023
@rveerd 不,我还没有登录,Express 应用程序是准系统,处于开发的初始阶段。

答:

1赞 Zegarek 11/20/2023 #1
  1. 在普通数据库上下文中,如果批量 DML(、,您的意思是“当我更新数据库时”)已执行但从未提交,或者池中的客户端已关闭自动提交/在事务中无意中运行,则会发生此类事情。我敢打赌前者:您应用批量更改的单独外部过程之后没有 .如果您从数据库客户端手动执行此操作,并通过随后在批量 DML 之后运行一些语句来验证您的更改是否已应用,则会显示它们确实可见,但这是因为先前语句产生的更改在同一事务中立即可见。insertupdatedeletetruncatemergecommitselectselect

  2. 这可能是混淆的标识符:如果系统的多个部分使用不同的大小写和引号规则对同一表进行寻址,则最终可能会得到多个不同的表。, , 并且都折叠成小写,除非您或处理查询的东西将标识符用双引号括起来 - 那么它将被逐字处理,并且只能使用双引号名称访问:doclistingsListingsLISTINGSLiStInGslistingslistings

    引用标识符也会使其区分大小写,而未引用的名称始终折叠为小写。

    您可以检查一下情况是否如此information_schema.tables

    select table_schema,table_name 
    from information_schema.tables 
    where table_name ilike '%listings%';
    
  3. 您还可以在不同的命名空间/架构中创建表的备用版本。如果存在以用户命名的架构(默认情况下,这些架构位于其他架构之前),并且您的客户端在与大型 DML 不同的用户下运行,则尤其可能发生这种情况。从第 2 点开始查询。也应该检测到这一点。listings

  4. 如果您在环境之间重复使用用户名、数据库名称和密码,并且在同一网络/机器上运行很多内容,则您的客户端可能正在其他地方连接,而不是您最终“通过终端”的地方。您可以彻底检查连接参数是否完全匹配,查看在什么位置、在哪个端口上运行什么。您可以通过一个渠道创建一个唯一的表格,并查看它是否通过另一个渠道可见。如果没有,它们可能正在连接不同的地方和/或存在事务隔离,而您忘记运行 .commit

  5. 可以使用行级安全性规则系统悄悄地更改可见性。前者就像在所有查询中添加了额外的、不可见的条件一样,后者可以完全重定向您的查询。

  6. express.js用于与数据库通信,因此除了显式发出语句外,没有办法绕过自动提交。如果您尝试在 pool.query() 中使用可重复读取可序列化的事务隔离级别,则不太可能但从技术上讲可能会毒害您的池:这将随机且悄悄地导致客户端被释放回池中,并保留数据库的旧快照。然后,每个客户都注定要在自己的平行宇宙中继续生活,在那里所有其他生命都不复存在,只有他们自己的行为才能做任何事情,直到它们发生或。这是一个很大的假设,假设客户端在释放回池时不会自动尝试提交。node-postgresBEGINcommitrollback