提问人:dovexz12323 提问时间:11/13/2023 最后编辑:Brian Tompsett - 汤莱恩dovexz12323 更新时间:11/20/2023 访问量:169
Express.js 不断返回数据库中不再存在的旧查询结果
Express.js keeps returning old query results that no longer exist in the database
问:
我正在将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');
}
});
它不断返回旧数据,不久前从数据库中删除,如何解决这个问题?
答:
在普通数据库上下文中,如果批量 DML(、,您的意思是“当我更新数据库时”)已执行但从未提交,或者池中的客户端已关闭自动提交/在事务中无意中运行,则会发生此类事情。我敢打赌前者:您应用批量更改的单独外部过程之后没有 .如果您从数据库客户端手动执行此操作,并通过随后在批量 DML 之后运行一些语句来验证您的更改是否已应用,则会显示它们确实可见,但这是因为先前语句产生的更改在同一事务中立即可见。
insert
update
delete
truncate
merge
commit
select
select
这可能是混淆的标识符:如果系统的多个部分使用不同的大小写和引号规则对同一表进行寻址,则最终可能会得到多个不同的表。, , 并且都折叠成小写,除非您或处理查询的东西将标识符用双引号括起来 - 那么它将被逐字处理,并且只能使用双引号名称访问:doc
listings
Listings
LISTINGS
LiStInGs
listings
listings
引用标识符也会使其区分大小写,而未引用的名称始终折叠为小写。
您可以检查一下情况是否如此
information_schema.tables
select table_schema,table_name from information_schema.tables where table_name ilike '%listings%';
您还可以在不同的命名空间/架构中创建表的备用版本。如果存在以用户命名的架构(默认情况下,这些架构位于其他架构之前),并且您的客户端在与大型 DML 不同的用户下运行,则尤其可能发生这种情况。从第 2 点开始查询。也应该检测到这一点。
listings
如果您在环境之间重复使用用户名、数据库名称和密码,并且在同一网络/机器上运行很多内容,则您的客户端可能正在其他地方连接,而不是您最终“通过终端”的地方。您可以彻底检查连接参数是否完全匹配,查看在什么位置、在哪个端口上运行什么。您可以通过一个渠道创建一个唯一的表格,并查看它是否通过另一个渠道可见。如果没有,它们可能正在连接不同的地方和/或存在事务隔离,而您忘记运行 .
commit
可以使用行级安全性或规则系统悄悄地更改可见性。前者就像在所有查询中添加了额外的、不可见的条件一样,后者可以完全重定向您的查询。
express.js
用于与数据库通信,因此除了显式发出语句外,没有办法绕过自动提交。如果您尝试在pool.query()
中使用可重复读取
或可序列化的
事务隔离级别,则不太可能但从技术上讲可能会毒害您的池:这将随机且悄悄地导致客户端被释放回池中,并保留数据库的旧快照。然后,每个客户都注定要在自己的平行宇宙中继续生活,在那里所有其他生命都不复存在,只有他们自己的行为才能做任何事情,直到它们发生或。这是一个很大的假设,假设客户端在释放回池时不会自动尝试提交。node-postgres
BEGIN
commit
rollback
评论