我有一个与此类似的问题,但不幸的是,那里没有给出答案,所以我将在这里描述我的情况。
我有一个多线程 Java Web 应用程序,我通过 Spring JDBC 访问 PostgreSQL 数据库。
在一个线程中,我可能会像这样刷新数据库中的物化视图(基于某些事件):
jdbcTemplate.execute(Queries.REFRESH_MATERIALIZED_VIEWS);
其中Queries.REFRESH_MATERIALIZED_VIEWS定义为:
String REFRESH_MATERIALIZED_VIEWS = "" +
"REFRESH MATERIALIZED VIEW blablabla1;" +
"REFRESH MATERIALIZED VIEW blablabla2;" +
"";
在另一个线程中,我还可以从同时更新的视图中读取数据。请注意,我没有CONCURRENTLY在语句中使用 SQL 关键字,因此根据这个问题和那个答案REFRESH,我希望视图被读锁定( ) (因为我希望始终从中获取“新鲜”数据)。AccessExclusiveLock
但似乎这种锁定并没有发生(或者我做错了什么),因为第二个线程有时会返回一个空集合。有时它会返回一个完全更新的集合。
看起来这里有一些同步问题,因为结果取决于时间。
所以问题是:如何确保访问这些视图的第二个线程总是获取更新的数据而不是空集合?是否有一些 Spring Data 内置机制来确保一致性?
有关交易的更新(基于评论)。
刷新是在单个事务中完成的,而不是读取,由于应用程序的多线程特性,这显然是不可能的:读取线程可能由调度程序产生,调度程序对其他线程及其事务一无所知,它们正在刷新同时查看。