Spring和Guice-persist都允许对访问数据库的方法进行@Transactional
注释,以便在没有打开时自动创建事务,在方法返回时提交,在异常时回滚等等。
如果在OSGi应用程序中不使用Spring或Guice,是否有办法获得相同的东西(或类似的可用)?
答案 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,或者更好的是......
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!)