2013-08-03 41 views
3

我有一个Web应用程序,目前只支持PostgreSQL作为后端,并有它自己的用户管理。使用Postgres认证机制使用通用用户帐户连接到数据库。这个应用程序现在应该得到一个审计日志,希望只有一些创建和更改的数据基于触发器和存储过程,并且出于性能方面的原因,如果一切工作异步并且独立于Web应用程序,那么将会很好。基于数据库的Web应用程序审计日志需要用户ID

存在一个主要问题:我们想知道Web应用程序的哪个用户进行了一些更改或创建的数据,但这些信息通常不适用于开箱即用的存储过程,因为我们使用通用账户。我想避免做的是调用Web应用程序中的存储过程,并以这种方式提供用户ID,因为这意味着可能会在Web应用程序中的相关位置添加相关调用。除此之外,我们在没有Web应用程序的情况下直接使用数据库更新数据模型,这意味着无论如何我们都需要触发器。

当前,Web应用程序正在处理每个请求上启动的事务并在其结束时执行。因此,我在每个请求中创建了一个临时表,它总是获取请求的当前用户ID,这些用户ID应该可用于由触发器在创建或更改的数据上执行的存储过程。

我不知道的一些事情是,如果执行的存储过程甚至可以访问数据库的当前事务并因此能够从临时表中检索当前用户标识?该表不是创建触发器的已更改数据的一部分。如果每个请求在最坏的情况下创建一个临时表来存储一个Integer,性能会受到怎样的影响?如果触发器能够访问临时表,则该请求可能随时完成,因为它的工作已完成或发生错误。这将如何影响一个触发器,该触发器将访问临时表,该临时表只在存储过程要读取用户标识时才提交或还原的事务中退出?

有没有其他方法可以将用户标识映射到触发器可以访问的事务的某个唯一标识符?除了临时表之外,我可以创建一个普通表,在每个请求开始时将用户标识映射到事务标识,但与当前事务无关。如果触发器现在获得负责执行触发器的事务ID,则存储过程可以使用事务ID来查找使用该事务的用户ID。

有什么想法?谢谢!

我添加了一个关于触发寿命和执行上下文,其适合于这个问题的问题:

execution context of database trigger in PostgreSQL

+0

是否databas会话用户之间共享? –

+0

不,目前存在与数据库的独特新连接,每个请求只有一个事务。但是我们计划在将来使用某种连接池,这种连接池可以提供多个请求的连接。我们目前不打算改变的是每个请求都由单个事务处理。 –

回答

4

的临时表似乎矫枉过正时,你可以只使用一个会话设置。

直到版本9.1,自定义会话变量需要在postgresql.confcustom_variable_classes参数中声明,这使得它在部署方面有点麻烦。

从9.2开始,就不再需要了。所以,你可以只发布在连接时:

SET myapp.myusername='foobar';

,然后在触发或者实际上在会话中的任何地方,SELECT current_setting('myapp.myusername'),或SHOW myapp.myusername会回到价值。

+0

如果你想要交易级别准则,'SET LOCAL'可以是有用的。 –

+0

触发器是否始终在触发执行的事件发生的客户端会话中完全执行?如果没有,会话值不会帮助我,因为会话在触发过程中可能已经关闭。如果是的话,绩效可能会受到审计日志的影响,我会尽量避免审计日志。 –

+0

我卡到PostgreSQL 8.4的那一刻,也是如此,并且需要改变它的配置,以获得一些价值不健全,对我有吸引力。我想我更喜欢像我描述的方法或使用后端pids的以下URL:http://www.depesz.com/2009/08/20/getting-session-variables-without-touching-postgresql-conf/ –

相关问题