2013-08-03 1 views
3

У меня есть веб-приложение, которое в настоящее время поддерживает PostgreSQL в качестве бэкэнд и имеет собственное управление пользователями. Подключение к базе данных выполняется с использованием общей учетной записи пользователя с использованием механизмов авторизации Postgres. Это приложение теперь должно получить журнал аудита для некоторых созданных и измененных данных, которые, надеюсь, основаны только на триггерах и хранимых процедурах, и по соображениям производительности было бы неплохо, если бы все работало как асинхронно, так и независимо от веб-приложения.Журнал аудита базы данных для веб-приложения нуждается в идентификаторе пользователя

Существует одна основная проблема: мы хотим знать, какой пользователь веб-приложения внес некоторые изменения или созданные данные, но эта часть информации обычно недоступна в хранимых процедурах из коробки, потому что мы подключаемся к Postgres, используя общий счет. То, что я бы хотел избежать, - это вызов хранимых процедур в веб-приложении и предоставление идентификаторов пользователей таким образом, поскольку это означало бы добавление соответствующих вызовов в возможные места в веб-приложении. Кроме того, мы делаем обновления модели данных напрямую, используя базу данных без веб-приложения, то есть нам нужны триггеры в любом случае.

В настоящее время веб-приложение работает со сделкой, начатой ​​по каждому запросу и совершенной на ее конце. Поэтому я хотел бы создать временную таблицу внутри транзакции в каждом запросе, который всегда получает текущий идентификатор пользователя запроса, который должен быть доступен для хранимых процедур, выполняемых триггерами при создании или изменении данных.

Некоторые вещи, которые я не знаю, - это если выполняемые хранимые процедуры могут даже получить доступ к текущей транзакции базы данных и, следовательно, могут извлечь текущий идентификатор пользователя из временной таблицы? Таблица не является частью измененных данных, для которых создан триггер. Как повлиять на производительность, если каждый запрос создает временную таблицу для хранения всего одного целого в худшем случае? Если триггер может получить доступ к временной таблице, запрос может быть завершен в любое время, потому что это работа или ошибки. Как это повлияет на триггер, который будет иметь доступ к временной таблице, которая только выходит из транзакции, которая будет зафиксирована или отменена, поскольку хранимые процедуры хотят прочитать идентификатор пользователя?

Есть ли другой способ, с помощью которого я могу сопоставить идентификатор пользователя с каким-то уникальным идентификатором транзакции, к которой имеет доступ триггер? Помимо временной таблицы, я мог бы создать обычную таблицу, в которой я сопоставляю идентификаторы пользователей с идентификаторами транзакций при запуске каждого запроса, но независимо от текущей транзакции. Если триггер теперь получит идентификатор транзакции, который отвечает за выполнение триггера, хранимые процедуры могут использовать идентификатор транзакции для поиска идентификатора пользователя, который использовал транзакцию.

Любые мысли? Благодаря!

Я добавил вопрос о спускового жизни и контекст исполнения, который подходит к этому вопросу:

execution context of database trigger in PostgreSQL

+0

Есть ли сеансы обмена данными между пользователями? –

+0

Нет, в настоящее время существует новое новое соединение с базой данных с одной транзакцией для каждого запроса. Но в будущем мы планируем использовать какой-то пул соединений, который обеспечивает соединения со сроком службы более одного запроса. То, что мы в настоящее время не планируем менять, заключается в том, что каждый запрос покрывается одной транзакцией. –

ответ

4

Временная таблица кажется излишним, когда вы могли бы просто использовать настройки сеанса.

до версии 9.1, пользовательские переменные сессии должны были быть объявлены в postgresql.conf через параметр custom_variable_classes, который сделал его немного громоздким, развертывание мудр.

Начиная с 9.2, он больше не нужен. Таким образом, вы могли бы просто выпустить во время соединения:

SET myapp.myusername='foobar';

, а затем в качестве триггера или фактически в любом месте в пределах сессии, SELECT current_setting('myapp.myusername') или SHOW myapp.myusername бы вернуть значение.

+0

'SET LOCAL' может быть полезна, если вы хотите видеть уровни транзакций. –

+0

Триггеры всегда полностью выполняются на этом клиентском сеансе, где произошло событие, которое привело к запуску триггера? Если нет, значения сеанса не помогут мне, потому что сеанс уже может быть закрыт во время запуска процесса. Если да, производительность может быть связана с протоколом аудита, который я постараюсь избежать как можно больше. –

+0

Я тоже придерживаюсь PostgreSQL 8.4, и мне нужно изменить его конфигурацию, чтобы получить некоторые значения, не кажется мне привлекательным. Я думаю, что предпочел бы такой подход, как я описал, или по следующему URL-адресу с использованием бэкэндов: http://www.depesz.com/2009/08/20/getting-session-variables-without-touching-postgresql-conf/ –

Смежные вопросы