Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在事务内部设置时间戳_Sql_Database_Postgresql_Transactions - Fatal编程技术网

Sql 在事务内部设置时间戳

Sql 在事务内部设置时间戳,sql,database,postgresql,transactions,Sql,Database,Postgresql,Transactions,我们在数据库PostgreSQL上有以下两个重复且独立运行的任务: 会话1在事务中执行一些更新,并设置更新数据集的时间戳: BEGIN; ... UPDATE table SET ..., timestamp = current_timestamp WHERE ...; ... // (A) COMMIT; 会话2选择自上次运行以来更新的所有数据集: SELECT * FROM table WHERE timestamp BETWEEN last_run AND current_timesta

我们在数据库PostgreSQL上有以下两个重复且独立运行的任务:

会话1在事务中执行一些更新,并设置更新数据集的时间戳:

BEGIN;
...
UPDATE table SET ..., timestamp = current_timestamp WHERE ...;
... // (A)
COMMIT;
会话2选择自上次运行以来更新的所有数据集:

SELECT * FROM table WHERE timestamp BETWEEN last_run AND current_timestamp;
last_run = current_timestamp;
...
如果会话2在会话1处于A时启动,它将看不到更改,因为时间戳在提交之前不会设置,而是设置为更早的值。 此外,后续会话2将不会选择更改,因为最后一次运行将已经大于时间戳。 因此,问题在于会话1在错误的时间将时间戳分别设置为错误的值,因此更改可能会被遗忘

一种可能的解决方法是在会话1中将更新的数据集ID存储在另一个表中,并在会话2中从该表中选择和删除它们。
但也许有人有更好的想法…

一个简单的解决方案是避免选择可能存在争用的行。选择上次\u运行和当前\u时间戳之间的行-间隔“1”分钟。您必须根据事务量以及更新事务完成所需的时间来确定您认为应该缓冲多长时间。只需确保您还设置了last_run=current_timestamp-interval“1”分钟,并且在选择开始之前没有提交的丢失行不应该有任何问题。

不时出现-据我所知,唯一完全可靠的方法是按照您所描述的方法,在第一个进程中将更新的ID存储在某个表中,并在第二个进程中将其标记为已处理。基本上,这是在数据库中重新创建消息队列。您已经很好地描述了一个简单的解决方案将如何错过更新

将导入过程标记为更新行非常容易,甚至可以使用数据表上的触发器来实现。如果您只有一个使用者进程,那么它所要做的就是从更新的\u item returning item\u id中删除,以获得更新列表。听起来要复杂得多,但事实并非如此。还可以免费监控积压工作的规模。IMHO session2必须选择zetimestamp>lastrun的位置,并将last运行设置为已处理项目的MAXtimestamp。正在运行但在session2运行期间有未提交数据的会话将在session2之前有时间戳,如果将last_run设置为current_timestamp,则在session2的后续运行中将隐藏这些会话


此外:在大多数情况下,不需要使用当前的时间戳。自然时间戳的值不能大于current_timestamp,因此每个现有时间戳将current_timestamp返回当前事务的开始时间,而不是当前时钟时间。选中,这将在当前事务中更改。

是否需要允许两者同时运行的机制?如果是这样,则需要准确的代码和业务逻辑。更常见的情况是,将每个事务块视为一个固定单元,当一个进程位于该块内时,其他进程无法启动该块。这直接避免了,但若一个人已经开始但并没有完成的问题。它是通过使用表/行锁实现的。您知道您更喜欢哪一种吗?必须可以同时运行它们。代码相当大,所以我无法发布,但任务1基本上导入数据,任务2导出更改。导出器必须每30分钟运行一次,并且不能等待可能的导入。导入程序的运行频率更高,但时间很短,无法等待导出程序运行约20分钟。正确。但它仍然比提交要早,这就是为什么我的解决方案能起作用。过去的MAXsomething总是在当前的时间戳=在提交时使用的时间之前。我们考虑过类似的事情。但是找到最佳的时间间隔是很困难的,因为我们有很短和很长的运行更新。