我们有一个Spring Transaction回滚问题,其中回滚似乎不起作用 .
在我的服务层方法中,用_1465194注释我调用三个不同的 DAOImpl
类来插入3条记录 .
中间插入从第4个表中获取以填充描述字段,但这会失败 . 我希望第一个插入回滚,但似乎没有发生 .
Few Points:
-
'Get'方法抛出运行时异常
-
我们正在使用
applicationContext.xml
中定义的org.springframework.jdbc.datasource.DataSourceTransactionManager
和MySQL datasource
. beans 在Beans.xml
中创建,导入ApplicationContext.xml
在 DAO
图层中
-
否
@Transactional
注释 -
我们在
applicationContext.xml
再次使用<tx:annotation-driven transaction-manager="transactionManager"/>
-
我们正在使用Spring 3.1
UPDATE :
代码片段....
服务类 - 这与我所拥有的相似......我在使用和不使用@Autowired时进行了测试 . 在服务类中调用事务启用方法 .
public class CustomerService {
//@Autowired
CustomerOrderDAO customerOrderDAOImpl;
//@Autowired
CustomerItemDAO customerItemDAOImpl;
//@Autowired
CustomerPromotionDAO customerPromotionDAOImpl;
//@Autowired
PromotionDAO promotionDAOImpl;
//other variables
public CustomerOrder handleIncomingOrders(CustomerOrder customerOrder) {
try {
saveOrderDetails(customerOrder);
.....
return customerOrder;
} catch (Exception e) //TO-DO catch proper exception
{
//Send error response
.......
return customerOrder;
}
}
@Transactional
public void saveOrderDetails(CustomerOrder customerOrder) throws Exception {
customerOrderDAOImpl.create(customerOrder);
....
while (promotionsIterator.hasNext()) {
customerPromotion.setPromotionName(promotionDAOImpl.getName(customerOrder.getPromotionId));
customerPromotionDAOImpl.create(customerPromotion);
}
......
while (customerItemIterator.hasNext()) {
customerItemDAOImpl.create(customerItem);
}
}
}
任何的想法?谢谢 .
2 回答
@Transactional
的默认行为是在对象周围添加了一个代理事务行为(在您的示例中为CustomerService
) . 从reference docs(向下滚动):在您的示例中,对
handlingIncomingOrders()
的外部调用将通过代理并命中目标对象(CustomerService
的实例) . 但是,对saveOrderDetails()
的后续调用是目标对象内部的常规方法调用,因此永远不会调用代理中的事务行为 . 但是,如果从另一个类调用saveOrderDetails()
,您会发现事务行为将按预期工作 .在您的情况下,解决方案将调用
saveOrderDetails(customerOrder);
作为proxyBean.saveOrderDetails(customerOrder);
其中proxybean is the Object on which
handleIncomingOrders`被调用 .如果
CustomerService
是singleton
(Defualt范围),它可以像将下面的代码添加到Service类一样简单 . (将自引用添加为自动装配)并在方法中使用它
如果它的范围是
Prototype
,那么可能的简单解决方案之一将如下 .您在哪里调用
handleIncomingOrders
使用以下代码中建议的更改 .