4

Spring と Guice-persist の両方で@Transactional、データベースにアクセスするメソッドにアノテーションを付けて、トランザクションが開いていない場合に自動的に作成し、メソッドの戻り時にコミットし、例外でロールバックするなどを許可します。

OSGi アプリケーションで Spring または Guice を使用せずに同じもの (または同様に使用可能) を取得する方法はありますか?

4

4 に答える 4

4

Guice/Spring @Transactional コンテナーで実行している場合でも、かなり頻繁に使用する次のコード スニペットがあります。

public void transact(Runnable runnable) {
    EntityTransaction tx = em.getTransaction();
    boolean success = false;
    tx.begin();
    try {
        runnable.run();
        success = true;
    } finally {
        if (success) {
            tx.commit();
        } else {
            tx.rollback();
        }
    }
}

public <T> T transact(Callable<T> callable) throws Exception {
    EntityTransaction tx = em.getTransaction();
    boolean success = false;
    tx.begin();
    try {
        T result = callable.call();
        success = true;
        return result;
    } finally {
        if (success) {
            tx.commit();
        } else {
            tx.rollback();
        }
    }
}

使用法:

dao.transact(new Runnable() {
    public void run() {
        // do stuff in JPA
    }
});

Long count = dao.transact(new Callable<Long>() {
    public Long call() {
        return em.createQuery("select count(*) from Foo", Long.class)
            .getSingleResult();
    }
});

その非常に軽量で、仕事を成し遂げます。

于 2012-04-13T19:22:54.400 に答える
2

Apache Aries を使用すると、blueprint.xml でトランザクションを宣言的に構成できます。例えば:

<blueprint
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0"
xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0">

<bean
    id="transactedBean"
    class="some.package.BeanImpl">
    <tx:transaction
        method="*"
        value="Required" />

Aries バンドルは、選択した OSGi フレームワークにドロップできます。

于 2012-04-13T16:14:26.197 に答える
0

考えられる解決策の1つは、Spring Data JPAを使用することです。これは、Springコンテナーの外部でとして使用できるためです。これを機能させるための有用な情報は、SpringContainerの外部でSpringDataJPAをどのように使用するかを参照してください。JpaRepositoryFactoryRepositoryFactorySupport

于 2012-04-13T14:46:42.243 に答える
0

問題を別の方法で見てみてはどうでしょうか。トランザクション プラミングを正確に実装する方法を考えるのではなく、transaction にラップされたものについて考えてみてください。ここで、 aは、コミットされるまでtransactionはあまり意味のない単なるラッパーです。

この言葉は奇妙に聞こえるかもしれませんし、多くの開発者を怖がらせますが、それは非常に理にかなっています..ここでモナドについて話すこと、またはもっと良いのは...

トランザクションモナド

trait Transactional[A] {
  def map[B]( f: A => B): Transactional[B]
  def flatMap[B]( f: A => Transactional[B] ): Transactional[B]
}

これはアプローチを説明する投稿ですが、要点は、コミットする準備が整うまで、副作用なしで関数を自由に適用することです(たとえば、トランザクション内で、たとえば、すべての関数出力を常に でラップするだけですTransactional) 。実際に「宇宙を変える」ための「コミット」(別名)。unsafePerformIO

上記はScalaでのもので、最初はMonadが非常に明白または望ましいものではないかもしれません.すごい!)

于 2012-04-13T15:16:22.840 に答える