我有一个关于实现postgresql触发器、最佳实践以及安全使用它们的一般问题。我很难提出有针对性的问题,因为我不知道我不知道什么,但我会尽我所能解释我的功能,然后问我的问题。
在我的rails应用程序中,我有一个功能,用户可以上传一个大的csv文件,其中包含数百万条需要导入应用程序的记录。偶尔,在这些大文件中会存在重复条目,我需要将这些重复条目记录到一个单独的表中。为了实现这个特性,我在Rails应用程序中以以下方式启用了一个触发器。下面是一些伪代码来说明我是如何做到这一点的。
#1. Rails Migration
def up
# Create the trigger
# This is a STATEMENT level AFTER INSERT trigger that writes to a duplicate log table
in the event that a duplicate entry is found.
end
def down
# drop the trigger
end
#2. pseudo code rails/sql code logic for importing the records.
ActiveRecord::Base.transaction do
1. Create a temporary table to upload the csv entries into. Drop on commit.
2. Enable the trigger that I created from the migration.
3. Import everything into the temporary table.
4. From the temporary table, insert the data into the real destination table. If
there is a duplicate unique constraint violation, do nothing.
5. After the insert is done on the destination table, execute the trigger to copy
all the duplicated entries into the duplicate table.
6. Disable the trigger.
end
我的问题如下。
这是在代码库中实现触发器的一种通常安全的方法吗?例如,如果另一个用户在第一个用户仍在处理时上传了另一个文件,这会干扰之前的上传吗?我读到临时表应该很好,因为即使它们的名称相同,psql也会为表创建自己的"scope/thread",但我不确定触发器是否会引发混乱。那里有危险吗?
我不想发生的是,这个触发器会导致多个用户在不同时间上传不同长度的文件,并有一些重叠。我不确定这是否会影响每个线程,或者我是否已经仔细隔离了它
此外,由于我是新手,所以这个过程还可能存在哪些需要注意的陷阱。如果可以的话,我会具体说明,但正如我之前提到的,我不知道我不知道什么。谢谢你的帮助。
PostgreSQL的事务系统将确保在应用程序中启用和禁用触发器时不会发生任何意外。
正如文件所说:
DISABLE/ENABLE [ REPLICA | ALWAYS ] TRIGGER
[…]
此命令获取一个
SHARE ROW EXCLUSIVE
锁。
锁兼容性矩阵显示该锁与自身以及表中除SELECT
和SELECT ... FOR SHARE/UPDATE
之外的所有内容冲突。因此,任何启用或禁用触发器的事务都将与所有其他数据修改一起序列化,并且不会出现竞争条件。