Grails可以确保在请求中的调用之间重用数据源连接吗?

时间:2012-08-07 14:46:41

标签: grails gorm

问题:使用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模式,这似乎意味着重用了相同的连接,但我只是猜测并且难以为此编写一个全面的测试。谢谢!

1 个答案:

答案 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的所有执行都将使用相同的连接。