我有一个具有应用程序范围的服务,而不是事务性的。Grails服务中的数据源注入
我有一个服务方法:
使用注入的dataSource创建[使用
Sql.call{...}
]存储过程调用。执行并遍历结果集。根据结果集,我将结果集细分为相同大小的块,并在多个线程中处理它们。
每个线程试图做
Sql sql = new Sql(dataSource)
这里发生死锁。
这是为什么? dataSource不会返回可能的新连接或空闲连接吗?
我有一个具有应用程序范围的服务,而不是事务性的。Grails服务中的数据源注入
我有一个服务方法:
使用注入的dataSource创建[使用Sql.call{...}
]存储过程调用。执行并遍历结果集。
根据结果集,我将结果集细分为相同大小的块,并在多个线程中处理它们。
每个线程试图做Sql sql = new Sql(dataSource)
这里发生死锁。
这是为什么? dataSource不会返回可能的新连接或空闲连接吗?
试图研究Gpars:这是一个时髦的并行化框架。
我碰到完全相同的问题。经过几个小时的搜索,我找到了解决方案。
在您的Datasource.groovy配置文件中,您可以设置连接池的参数到数据库。
我已经改变了http://commons.apache.org/proper/commons-dbcp/apidocs/org/apache/commons/dbcp/BasicDataSource.html让我CONFIGFILE看起来像这样的minIdle
,maxIdle
和maxActive
设置:
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'
}
当你是不是在交易,你必须释放连接是GroovySQL从数据源中提取。游泳池没有连接,这就是为什么它锁定。
在事务内TransactionAwareDataSourceProxy将负责共享连接,因此在这种情况下不需要从GroovySQL释放连接。有关详细信息,请参阅http://jira.grails.org/browse/GRAILS-5454。
这是在Grails中使用GroovySQL的更好方法,因为OpenSessionInView(OSIV)拦截器将负责关闭连接,并且它将与Hibernate共享相同的数据库连接。这种方法适用于两种情况:内部交易和外部交易。
Sql sql = new Sql(sessionFactory.currentSession.connection())
线程停止的地方,你可以给堆栈跟踪吗?你知道这是一个真正的死锁(2资源互锁),而不是普通的等待被阻止的资源? – 2011-02-17 14:55:18
你的数据源是如何配置的?您是使用默认设置还是您定义了不同的最大连接数值?您的存储过程中是否有长时间运行的查询?有没有任何类型的堆栈跟踪? – 2011-06-15 21:36:52