« coroid ver.0.3.0 全ランキングと詳細情報表示対応 | トップページ | Android web browserのajax(asynchronous request)の挙動が変だ »

2010/03/28

Grailsでワーカスレッドを作ってそこからHibernateで永続化したい、んだけれど…

coroidでは、動画変換serviceを作って、そこで動画の処理を行っています。その中で、処理の経過を永続化しています。

class NicoContentService
    def transcode(){
        // (1)処理開始状態を永続化
        // (2)変換処理
        // (3)処理終了状態を永続化
    }
}

(2)が重たい処理なので、ワーカスレッドを作成し、処理完了を待たずに制御を戻すことにしました。

class NicoContentService
    def transcode(){
        Thread.start{
            // (1)処理開始状態を永続化
            // (2)変換処理
            // (3)処理終了状態を永続化
        }
    }
}

coroid ver.0.1.0まではこのような実装でした。これでGrails1.1.1ではうまく動いていたのですが、1.2.1にバージョンを上げるとこちらに書かれている通り、

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

という例外が出るようになりました。これは、Thread.startで作ったワーカスレッドがHibernateのセッションを持っていないので発生したのでしょう。1.1.1では、セッションが必要になればGrailsフレームワーク側で自動で取得していたのではないかと想像します。また、1.2.1でも、Grailsフレームワーク側を変更すればそのような動作にできるようです(参考)。Grailsの中で使用しているSpringFrameworkのHibernateTemplateクラスコンストラクタに渡す引数を変更する、という対応のようです。

coroidはGrailsを含めて配布しているわけではないので、上記の対応は採用できません。他の方法を探したところ、BackgroundThread pluginというものがありました。このプラグインの説明に以下のような記述がありましたので、問題を解消できるだろうと考えました。

Beyond the inherent difficulty of concurrent programming, Grails had a few other difficulties: most significantly, the Hibernate session is bound to the thread, and so threads need to do their own Hibernate session management. This plugin takes care of those issues.

このプラグインを用い、以下のようにソースを変更しました。これがcoroid ver.0.2.0です。

class NicoContentService
    def transcode(){
        backgroundService.execute("Working for converting",{
            // (1)処理開始状態を永続化
            // (2)変換処理
            // (3)処理終了状態を永続化
        })
    }
}

 

ここからが問題です。

こちらに記載した通り、次のバージョンでは処理の進捗率を表示させたいと考えています。この情報は、さきゅばすが通知するステータステキスト(さきゅばすをGUIで起動して変換処理を行ったとき、画面下部のステータスバーに表示される情報です)を加工して永続化すれば良いと考えました。

この通知は、さきゅばすが作成するワーカスレッドが行います。つまり、この処理を追加することで、backgroundServiceワーカスレッドとはまた別のスレッドでHibernateを利用する必要がでてきた、ということです。

backgroundThread pluginのソースコードBackgroundThreadManager.javaを見ると、Hibernateセッションを以下のように取り扱っていました。パッケージ名を見るにつけ、どうやらSpring Frameworkの機能を利用しているようです。

開始時(bind):

Session session = SessionFactoryUtils.getSession(sessionFactory, true);
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));


終了時(unbind):

SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.getResource(sessionFactory);
TransactionSynchronizationManager.unbindResource(sessionFactory);
SessionFactoryUtils.closeSession(sessionHolder.getSession());

上記と同じようなコードを、さきゅばすのワーカスレッド永続化処理に追加してみたのですが、”(3)処理終了状態を永続化”のところで以下の例外が出ました。

ERROR events.PatchedDefaultFlushEventListener  - Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect):

さて、これをどう解決すればよいやら。Springも絡んできそうな様相なのですが、さっぱり知らないし、というところです。

« coroid ver.0.3.0 全ランキングと詳細情報表示対応 | トップページ | Android web browserのajax(asynchronous request)の挙動が変だ »

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/18902/47932497

この記事へのトラックバック一覧です: Grailsでワーカスレッドを作ってそこからHibernateで永続化したい、んだけれど…:

« coroid ver.0.3.0 全ランキングと詳細情報表示対応 | トップページ | Android web browserのajax(asynchronous request)の挙動が変だ »

other sites

  • follow us in feedly
  • github
  • stackoverflow

ソフトウェアエンジニアとして影響を受けた書籍

  • Christain Bauer: HIBERNATE イン アクション

    Christain Bauer: HIBERNATE イン アクション
    理論と実践が双方とも素晴らしい製品であるHibernate。本書はそのプロダクトを書名に冠していますが、Hibernateを使うつもりがなく、ORマッピングの解説書として読むにしても十分な良書です。Second EditionとしてJava Persistence With Hibernateという書籍も出版されていますが、残念ながら現在のところ 和訳はされていません。-インアクションは2.xの、Java Persistence-は3.1の頃のものなので、最新版とはちょっと違うところもあることに注意。 (★★★★★)

  • アンドリュー・S・タネンバウム: 分散システム 原理とパラダイム 第2版

    アンドリュー・S・タネンバウム: 分散システム 原理とパラダイム 第2版
    クライアント/サーバシステムを構築する上で必要となる知識が総論されてます。Web技術者も、フレームワーク部分を開発するのであれば必読。 (★★★★★)

  • Joel Spolsky∥著: ジョエル・オン・ソフトウェア

    Joel Spolsky∥著: ジョエル・オン・ソフトウェア
    前述の書籍「ソフトウエア開発プロフェッショナル」をより砕いたもの、という感じでしょうか。 前書きではプログラマでなくSE向けの本のように書かれているが、プログラマが読んでも面白い本であると思われます。 SEになった新人(あるいはそういう会社に入る/入りたての人)にとっては、これからどういったことが仕事を遂行していく上で起こりえるのか、どのように考えて行なっていけばいいのか決定する助けになると思います。 元は″Joel on Software″というブログの記事で、web上でも一部日本語で読めます。 http://japanese.joelonsoftware.com/ (★★★)

  • ドナルド・C・ゴース,ジェラルド・M・ワインバーグ: ライト、ついてますか

    ドナルド・C・ゴース,ジェラルド・M・ワインバーグ: ライト、ついてますか
    問題解決(一昔前のの流行語で言うところの『ソリューション』)能力は、システムエンジニアのスキルとして備えるべきもののうちのひとつです。しかし、これは難しい。学校で出されるテストと違い、唯一の、(問題提出者が想定している)解を求めるだけが「問題解決」では無いからです。そもそも、何が問題なのか、それは本当に問題なのか、それは本当に解決すべき問題なのか、その問題解決方法は正しいのか、などを解決しなければ、「その解は正しいのか」に辿りつくことができません。この本の最も良いところのひとつは、本があまり厚くないこと。すぐに読めるし、何回も読み返す気になるでしょう。 (★★★★★)

  • スティーブ・マコネル: ソフトウエア開発プロフェッショナル

    スティーブ・マコネル: ソフトウエア開発プロフェッショナル
    コードコンプリートで有名なスティーブマコネルの著書。新人SEに読んで欲しい。個人として業界の中でどうあるべきか、組織としてどうあるべきか、SEのプロ意識とは?SEの心構え概論、といったところでしょうか。また、業界における資格の重要性についても説かれています。この業界では資格が特に軽んじられる傾向がありますが、この傾向はどんな弊害をもたらすのか、将来的にこの業界は資格に対してどのような姿勢で臨んでいくべきなのか。日経BP社では(他の出版社もだが)最近、似たような類いのあまり面白くない書籍が乱出版されていますが、この本は別格だと思うので安心して購入して欲しいと思います。 (★★★★★)

無料ブログはココログ