2011-02-17 73 views
2

我有一个具有应用程序范围的服务,而不是事务性的。Grails服务中的数据源注入

我有一个服务方法:

  1. 使用注入的dataSource创建[使用Sql.call{...}]存储过程调用。执行并遍历结果集。

  2. 根据结果集,我将结果集细分为相同大小的块,并在多个线程中处理它们。

  3. 每个线程试图做Sql sql = new Sql(dataSource)

  4. 这里发生死锁。

这是为什么? dataSource不会返回可能的新连接或空闲连接吗?

+0

线程停止的地方,你可以给堆栈跟踪吗?你知道这是一个真正的死锁(2资源互锁),而不是普通的等待被阻止的资源? – 2011-02-17 14:55:18

+0

你的数据源是如何配置的?您是使用默认设置还是您定义了不同的最大连接数值?您的存储过程中是否有长时间运行的查询?有没有任何类型的堆栈跟踪? – 2011-06-15 21:36:52

回答

0

试图研究Gpars:这是一个时髦的并行化框架。

0

我碰到完全相同的问题。经过几个小时的搜索,我找到了解决方案。

在您的Datasource.groovy配置文件中,您可以设置连接池的参数到数据库。

我已经改变了http://commons.apache.org/proper/commons-dbcp/apidocs/org/apache/commons/dbcp/BasicDataSource.html让我CONFIGFILE看起来像这样的minIdlemaxIdlemaxActive设置:

dataSource { 
    url = "jdbc:mysql://127.0.0.1/sipsy_dev?autoReconnect=true&zeroDateTimeBehavior=convertToNull" 
    driverClassName = "com.mysql.jdbc.Driver" 
    username = "sipsy_dev" 
    password = "sipsy_dev" 
    pooled = true 
    properties { 
    minEvictableIdleTimeMillis=1800000 
    timeBetweenEvictionRunsMillis=1800000 
    numTestsPerEvictionRun=3 
    testOnBorrow=true 
    testWhileIdle=true 
    testOnReturn=true 
    minIdle=100 
    maxIdle=250 
    maxActive=500 
    validationQuery="SELECT 1" 
    } 
    dialect = 'org.hibernate.dialect.MySQL5InnoDBDialect' 
} 
0

当你是不是在交易,你必须释放连接是GroovySQL从数据源中提取。游泳池没有连接,这就是为什么它锁定。

在事务内TransactionAwareDataSourceProxy将负责共享连接,因此在这种情况下不需要从GroovySQL释放连接。有关详细信息,请参阅http://jira.grails.org/browse/GRAILS-5454

这是在Grails中使用GroovySQL的更好方法,因为OpenSessionInView(OSIV)拦截器将负责关闭连接,并且它将与Hibernate共享相同的数据库连接。这种方法适用于两种情况:内部交易和外部交易。

Sql sql = new Sql(sessionFactory.currentSession.connection())