2013-08-03 40 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/ –

相關問題