我对Spring中的事务有这种奇怪的行为。
我有两个班级:
doGenericServiceStuff首先调用的服务类(由另一个已拥有事务的对象调用):
SYSTEM
然后调用一些ServiceClass的CommonBusinessClass'方法:
@Service("myService")
public class ServiceClass {
public void doGenericServiceStuff(Object someBean){
BusinessI business = BusinessFactory.getBusinessForObject(someBean); //Here, returns the commonBusinessClass bean
business.doGenericBusinessStuff(someBean);
}
/*@Transactional (readOnly=false, rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW)*/
public void firstOperation(Object o){
//multiple database insert and stuff
}
/*@Transactional (readOnly=false, rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW)*/
public void secondOperation(Object o){
//also multiple database insert and stuff
}
}
免责声明:显然,我不会像这样操纵@Bean("commonBusinessClass")
public class CommonBusinessClass implements BusinessI{
@Autowired
@Qualifier("myService")
protected ServiceClass = null;
@Transactional(rollBackFor=Exception.class, Propagation=Propagation.MANDATORY)
public Object doGenericBusinessStuff(Object o){
service.firstOperation(o);
service.secondOpertion(o);
//There can be stuff here in other BusinessClass
return o;
}
}
而我也不会调用我的方法Objects
。但是,ServiceClass会调用CommonBusinessClass,而CommonBusinessClass又调用ServiceClass。也许这是糟糕的设计,也许是它无法正常工作的原因,但这就是我现在所拥有的。
doGenericStuff()
中的方法不是Transactional(因此是注释),而ServiceClass
是(doGenericBusinessStuff()
)。
新要求是,如果Propagation.MANDATORY
失败(并且回滚)secondOperation()
应该被提交。所以我为firstOperation()
和@Transactional
(评论中的那些)添加了firstOperation()
。我期待它能够正常工作(secondOperation()
中的例外不会回滚secondOperation()
中已经完成的事情),但事实并非如此。但是,如果我删除了firstOperation()
上的@Transactional
,那就可以了。
这种行为是否正常,或者在我的实际应用程序中还有其他东西在我放在这里(因为我简化了)?为什么新创建的交易会以任何方式相互关联?关于可能发生什么的任何想法?
提前致谢。
答案 0 :(得分:1)
您需要了解交易的背景。如果将方法标记为事务性,则意味着该方法中的每个操作都将被视为一个操作。如果一切正常,那么事务就会被提交,但是如果出现问题,那么整个事务就会被回滚。
在你的情况下,你有:
@Transactional(rollBackFor=Exception.class, Propagation=Propagation.MANDATORY)
public Object doGenericBusinessStuff(Object o){
service.firstOperation(o);
service.secondOpertion(o);
//There can be stuff here in other BusinessClass
return o;
}
因此,如果service.firstOperation(o)
失败,那么整个事务将被回滚,而service.secondOpertion(o)
则相同。如果service.secondOpertion(o)
失败,doGenericBusinessStuff
内的所有操作都将被收回。
编辑:如果您使用JtaTransactionManager,则REQUIRES_NEW在某些情况下可能无效:
注意:实际的交易暂停不会开箱即用 所有交易经理。这尤其适用于 的JtaTransactionManager