Gen*_* S. 38 java spring hibernate
我有一个做一堆事情的方法; 其中包括一些插入和更新.它如此宣布......
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
public int saveAll(){
 //do stuff;
}
它完全按照预期工作,我没有任何问题.然而,有些情况下我想强制回滚,尽管没有例外......目前,当我遇到合适的条件时,我强迫异常,但它很难看,我不喜欢它.
我可以以某种方式主动调用回滚吗?这个例外叫它......我想也许我也可以.
ska*_*man 24
在Spring Transactions中,您使用TransactionStatus.setRollbackOnly().  
你在这里遇到的问题是你@Transactional用来划分你的交易.这具有非侵入性的好处,但它也意味着如果您想手动与事务上下文交互,则不能.
如果要严格控制事务状态,则必须使用编程事务而不是声明性注释.这意味着使用Spring的TransactionTemplate,或直接使用其PlatformTransactionManager.请参见Spring参考手册的第9.6节.
使用TransactionTemplate,您提供一个实现的回调对象TransactionCallback,并且此回调中的代码可以访问这些TransactionStatus对象.
它不是那么好@Transactional,但你可以更好地控制你的tx状态.
Jak*_*kub 17
我们不使用EJB,而是简单的Spring,我们选择了AOP方法.我们已经实现了新的注释,@TransactionalWithRollback并使用AOP用"around"建议包装带注释的方法.实施我们提到的建议TransactionTemplate.这意味着一开始就做了一点工作,但结果我们可以@TransactionalWithRollback像我们@Transactional在其他情况下使用的那样注释一个方法.主要代码看起来干净简单.
//
// Service class - looks nice
//
class MyServiceImpl implements MyService {
    @TransactionalWithRollback
    public int serviceMethod {
        // DO "read only" WORK
    }
}
//
// Annotation definition
//
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface TransactionalWithRollback {
}
//
// the around advice implementation
//
public class TransactionalWithRollbackInterceptor {
    private TransactionTemplate txTemplate;
    @Autowired private void setTransactionManager(PlatformTransactionManager txMan) {
        txTemplate = new TransactionTemplate(txMan);
    }
    public Object doInTransactionWithRollback(final ProceedingJoinPoint pjp) throws Throwable {
        return txTemplate.execute(new TransactionCallback<Object>() {
            @Override public Object doInTransaction(TransactionStatus status) {
                status.setRollbackOnly();
                try {
                    return pjp.proceed();
                } catch(RuntimeException e) {
                    throw e;
                } catch (Throwable e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }
}
//
// snippet from applicationContext.xml:
//
<bean id="txWithRollbackInterceptor" class="net.gmc.planner.aop.TransactionalWithRollbackInterceptor" />
<aop:config>
    <aop:aspect id="txWithRollbackAspect" ref="txWithRollbackInterceptor">
        <aop:pointcut 
            id="servicesWithTxWithRollbackAnnotation" 
            expression="execution( * org.projectx..*.*(..) ) and @annotation(org.projectx.aop.TransactionalWithRollback)"/>
        <aop:around method="doInTransactionWithRollback" pointcut-ref="servicesWithTxWithRollbackAnnotation"/>
    </aop:aspect>
</aop:config>
小智 16
这对我有用:
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
Edw*_*ges 15
如果您在EJB中,请调用setRollbackOnly()它SessionContext.
你可以这样注射SessionContext:
public MyClass {
    @Resource
    private SessionContext sessionContext;
    @Transactional(propagation = Propagation.REQUIRED, 
                   isolation = Isolation.DEFAULT, 
                   readOnly = false)
    public int saveAll(){
        //do stuff;
        if(oops == true) {
             sessionContext.setRollbackOnly();
             return;
        }
    }
setRollbackOnly()是...的成员EJBContext.  SessionContext扩展EJBContext:http:
 //java.sun.com/j2ee/1.4/docs/api/javax/ejb/SessionContext.html   注意它只在会话EJB中可用.
@Resource是标准的Java EE注释,因此您应该检查Eclipse中的设置.这是一个如何使用注入SessionContext 的示例@Resource.
我怀疑这可能不是你的解决方案,因为看起来你可能没有使用EJB  - 解释为什么Eclipse没有找到@Resource.
如果是这种情况,那么您将需要直接与事务交互 - 请参阅事务模板.