以前は MySQL でスムーズに実行されていた Grails 2.0 アプリケーションを開発します
私たちは管理者から、彼らが好むPostgreSQLに切り替えるように依頼してきました
アプリケーションに多くの新機能を追加しました。その中には、現在問題を引き起こしているものも含まれます: 非同期のサードパーティ Web サービス リクエスト
これで、ドメイン オブジェクトが作成されました。それを Question と呼びましょう。afterInsert
クロージャーを使用するResource
と、外部 Web サービスへの呼び出しの結果を後で保存するために が作成されます。
class Question implements Serializable {
static hasMany = [resources: Resource]
static constraints = {
resources(nullable: true)
}
def afterInsert() {
Resource.withNewSession {
Resource txt = Resource.create(null)
this.addToResources(txt)
}
}
Resource retrieveResource(){
return this.resources.find{ it instanceof Resource }
}
static Question create(Map params) throws SaveDomainException {
//question creation
}
}
次のような質問を作成します。
//first we create question and save it
def question = Question.create(params)
question.save(flush:true, insert:true)
getThirdPartyService().doCallAsync((int)req.retrieveResource().id)
そして、上記のように取得した Id を使用して単純なを実行する (これが恐ろしい「Hibernate Session - Thread」の問題にならないように、executors grails プラグインを介して取得される)を生成するThirdPartyService
メソッドとしてdoCallAsync
ExecutorService
Resource.get(res_id)
問題は、PostgreSQL とpooled = true
ではDataSource.groovy
、get
が null を返したり、リソース オブジェクトを返したりすることです。
get(id)
a 、 a findById(id)
、およびexecuteQuery
select を使用したanの 3 つの異なるリクエストでテストしました。
さらに奇妙なのは、上記の 3 行を同じ方法で使用すると、結果が異なる場合があることです。3つのうち1つだけがnullを返すか、3つがnullを返すか、または何も返さない(これは予想される動作です、思い出します)
Hibernate キャッシュの問題であるかどうかを確認するために PostgreSQL クエリ ログをオンにしましたが、3 つの要求がすべてログに表示されるため、Hibernate はデータベースに毎回ヒットします。正しい ID を持つリソースの挿入、コミット、3 つの選択 (正しいリソース ID が提供されます) が続きます。
このバグがどこから来るかを確認するためにさらにテストする内容について、誰かヒントはありますか? (接続プールを変更しようとしましたが、うまくいきませんでした)
Thread.sleep(1000)
最後に、要求の前に a (これは血みどろですが、テストのみを目的としています ;-) )を追加すると、すべてがスムーズに実行されます。したがって、postgres プロセス間の可視性の問題のようですが、それを解決する方法についての手がかりはありません。