Spring と Guice-persist の両方で@Transactional
、データベースにアクセスするメソッドにアノテーションを付けて、トランザクションが開いていない場合に自動的に作成し、メソッドの戻り時にコミットし、例外でロールバックするなどを許可します。
OSGi アプリケーションで Spring または Guice を使用せずに同じもの (または同様に使用可能) を取得する方法はありますか?
Spring と Guice-persist の両方で@Transactional
、データベースにアクセスするメソッドにアノテーションを付けて、トランザクションが開いていない場合に自動的に作成し、メソッドの戻り時にコミットし、例外でロールバックするなどを許可します。
OSGi アプリケーションで Spring または Guice を使用せずに同じもの (または同様に使用可能) を取得する方法はありますか?
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();
}
});
その非常に軽量で、仕事を成し遂げます。
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 フレームワークにドロップできます。
考えられる解決策の1つは、Spring Data JPAを使用することです。これは、Springコンテナーの外部でとして使用できるためです。これを機能させるための有用な情報は、SpringContainerの外部でSpringDataJPAをどのように使用するかを参照してください。。JpaRepositoryFactory
RepositoryFactorySupport
問題を別の方法で見てみてはどうでしょうか。トランザクション プラミングを正確に実装する方法を考えるのではなく、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が非常に明白または望ましいものではないかもしれません.すごい!)