如果没有Guice / Spring,JPA交易会减少痛苦

时间:2012-04-13 13:16:12

标签: spring jpa transactions osgi guice

Spring和Guice-persist都允许对访问数据库的方法进行@Transactional注释,以便在没有打开时自动创建事务,在方法返回时提交,在异常时回滚等等。

如果在OSGi应用程序中不使用Spring或Guice,是否有办法获得相同的东西(或类似的可用)?

4 个答案:

答案 0 :(得分: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();
    }
});

它非常轻巧,可以完成任务。

答案 1 :(得分: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框架中。

答案 2 :(得分:0)

一种可能的解决方案是使用Spring Data JPA,can be used outside Spring container使用JpaRepositoryFactory作为RepositoryFactorySupport。有关实现此功能的有用信息位于How do you use Spring Data JPA outside of a Spring Container?

答案 3 :(得分:0)

如何以不同的方式查看问题,而不是考虑如何实现事务管道,考虑事务中包含的东西,其中transaction只是一个包装器直到承诺才真正意义重大。

这个词可能听起来很怪异并且吓跑了许多开发者,但它确实很有意义..在这里谈论Monad,或者更好的是......

Transactional Monad

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

这是一个讨论方法的post,但要点是自由地应用函数而没有任何副作用(例如在事务中,例如它总是只包含Transactional中的所有函数输出) 直到你准备提交,然后你调用“提交”(又名unsafePerformIO)来实际“改变宇宙”。

以上是在Scala中,也许Monad最初可能不是非常明显或可取的东西,但它只是看待问题的另一种方式=&gt;例如没有框架,AOP,突变等。只是纯粹的功能组合(FTW!)