【发布时间】:2013-08-04 20:33:46
【问题描述】:
我有一个 Web 应用程序,它目前只支持 PostgreSQL 作为后端,并且有自己的用户管理。使用 Postgres 身份验证机制使用通用用户帐户完成与数据库的连接。此应用程序现在应该获得一些创建和更改的数据的审核日志,希望仅基于触发器和存储过程,并且出于性能原因,如果一切工作异步且独立于 Web 应用程序,那就太好了。
有一个主要问题:我们想知道 Web 应用程序的哪个用户进行了一些更改或创建了数据,但是该信息通常在开箱即用的存储过程中不可用,因为我们使用泛型连接到 Postgres帐户。我想避免做的是调用 Web 应用程序中的存储过程并以这种方式提供用户 ID,因为这意味着在 Web 应用程序的可能位置添加相关调用。除此之外,我们在没有 Web 应用程序的情况下直接使用数据库对数据模型进行更新,这意味着我们无论如何都需要触发器。
目前,Web 应用程序正在处理从每个请求开始并在其结束时提交的事务。因此,我会在每个请求的事务中创建一个临时表,该表始终获取请求的当前用户 id,该用户 id 应该可用于触发器对创建或更改的数据执行的存储过程。
有些事情我不知道,执行的存储过程是否甚至可以访问数据库的当前事务,从而能够从临时表中检索当前用户 ID?该表不是为其创建触发器的更改数据的一部分。如果在最坏的情况下每个请求都创建一个临时表来存储一个 Integer,性能会受到怎样的影响?如果触发器能够访问临时表,则请求可能随时完成,因为它的工作已完成或出现错误。这将如何影响可以访问临时表的触发器,该临时表仅在事务中退出,因为存储过程想要读取用户 ID,所以该事务被提交或恢复?
有没有其他方法可以将用户 ID 映射到触发器有权访问的事务的某个唯一标识符?除了临时表之外,我还可以创建一个普通表,在该表中,我在每个请求开始时将用户 ID 映射到事务 ID,但与当前事务无关。如果触发器现在将获取负责执行触发器的事务 id,则存储过程可以使用事务 id 来查找使用该事务的用户 id。
有什么想法吗?谢谢!
我添加了一个关于触发器生命周期和执行上下文的问题,适合这个问题:
【问题讨论】:
-
用户之间是否共享数据库会话?
-
不,目前有一个独特的新数据库连接,每个请求都有一个事务。但我们计划在未来使用某种连接池,它提供生命周期超过一个请求的连接。我们目前不打算改变的是每个请求都包含在一个事务中。
标签: sql postgresql stored-procedures triggers audit