问题:使用grails,SQL Server和DBA希望使用触发器来审核用户数据库活动(我知道审计插件)。他们建议在每次数据库调用之前设置SQL Server的CONTEXT_INFO,在上下文中设置用户名,然后由触发器提取。我正在考虑的是增加GORM save等。像这样的方法:
private replaceSave(domainClass) {
def saveMethod = domainClass.metaClass.pickMethod("save", [Map] as Class[])
domainClass.metaClass.save = { Map params ->
def sql = new Sql(dataSource)
sql.execute("DECLARE @U varbinary(0128);SET @U = CONVERT(varbinary(0128),'the-username');SET CONTEXT_INFO @U;")
saveMethod.invoke(delegate, [params] as Object[])
sql.execute("DECLARE @U varbinary(0128);SET @U = CONVERT(varbinary(0128),'');SET CONTEXT_INFO @U;")
}
}
我不知道这种技术是否能确保saveMethod使用的dataSource连接与Sql对象连接使用的连接相同。我的理解是Grails使用OpenSessionInView模式,这似乎意味着重用了相同的连接,但我只是猜测并且难以为此编写一个全面的测试。谢谢!
答案 0 :(得分:-1)
好的,试着改善答案:
查看groovy.sql.Sql,您可以看到如果使用dataSource创建实例,则对于每个执行,该类将使用dataSource.getConnection()
。今天有了Oracle,我遇到了两个不同的会话。我不得不使用sql.cacheConnection
来解决它。
所以:
//this depends on the dataSource.getConnection()
Sql sql = new Sql(dataSource)
//this will always use the same connection
Sql sql = new Sql(connection)
如果我没弄错的话,grails域类方法使用的连接在sessionFactory
中是可用的。我不知道您在哪里定义replaceSave
方法,但如果您有权访问sessionFactory
,则可以确保该流程将使用相同的连接:
Sql sql = new Sql(sessionFactory.currentSession.connection())
这确保了groovy sql的所有执行都将使用相同的连接。