我们有一个Spring事务回滚问题,其中回滚似乎不起作用
在用@Transactional
注释的服务层方法中,我调用三个不同的DAOImpl
类来插入3条记录
中间插入从第四个表执行get以填充描述字段,但此get失败。我希望第一次插入会回滚,但它似乎没有发生
几点:
org.springframework.jdbc.datasource.DataSourceTransactionManager
和MySQL数据源
中定义的应用ontext.xml
。Bean是在Beans.xml
中创建的,它被导入到Application ationContext.xml
DAO
层@Transactional
注释
更新:
代码片段......
服务类-这与我所拥有的类似。。。。我测试了是否有@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);
}
}
}
任何想法?谢谢。
在您的情况下,解决方案将调用SaveOrder细节(客户订单);
作为proxyBean.save订单细节(客户订单);
其中proxybean是调用
handleIncomingOrders'的对象。
如果CustomerService
是singleton
(定义范围),则只需将以下代码添加到服务类即可。(将自参考添加为自动连线)
//@Autowired
CustomerService customerService; // As this is injected its a proxy
在方法中,将其用作
public CustomerOrder handleIncomingOrders(CustomerOrder customerOrder) {
try {
customerService.saveOrderDetails(customerOrder);
.....
return customerOrder;
} catch (Exception e) //TO-DO catch proper exception
{
//Send error response
.......
return customerOrder;
}
}
如果其范围为原型,则可能的简单解决方案如下。
public CustomerOrder handleIncomingOrders(CustomerOrder customerOrder, CustomerService customerService) {
try {
customerService.saveOrderDetails(customerOrder);
.....
return customerOrder;
} catch (Exception e) //TO-DO catch proper exception
{
//Send error response
.......
return customerOrder;
}
}
在调用handleIncomingOrders
的地方,请使用下面代码中建议的更改。
bean.handleIncomingOrders(customerOrder); //Suppose this is old code
Change it to
bean.handleIncomingOrders(customerOrder, bean);// THough it appears as we are sending reference to `THIS` as parameter whcihc can be unnecessary, in case of `Proxy`while inside your method `this` and `Passed reference` will point to different Obejects.
@Transactional
的默认行为是在对象周围添加了代理的事务性行为(示例中的CustomeService
)。从参考文档(向下滚动):
在代理模式(这是默认模式)下,只截获通过代理传入的外部方法调用。这意味着自调用,实际上是目标对象内调用目标对象另一个方法的方法,即使调用的方法标记为@Transactional,在运行时也不会导致实际事务。
在您的示例中,对handlingIncomingOrders()
的外部调用通过代理并命中目标对象(CustomerService
的实例)。但是,对saveOrderDetails()
的后续调用是目标对象内部的正常方法调用,因此永远不会调用代理中的事务行为。但是,如果从另一个类调用了saveOrderDetails()
,您会发现事务行为将按预期工作。
如果我没有捕捉到运行时异常,我就不会得到hibernate异常(不要刷新会话..)
这很好,但并不总是在代码中抛出运行时异常。因此,我挖掘并发现如下所示的rollbackFor; 现在,我必须更改所有代码,以使用RollBackfor更改@Transactional。但是还有其他方法可以将所有@transaction advice属性更改为rollbackFor=exception.class吗?
问题内容: 我正在使用TestNG 6.9.9来构建回归测试环境。但是遇到使用JUnit时从未遇到过的问题。在我看来,当每个测试用例完成时,如果测试方法在与调用方法相同的事务上下文中运行,则默认情况下将自动回滚每个数据的更改。但这似乎不是事实,而且我无法找出我的代码中是否有任何错误。请帮帮我。pom.xml中的属性,指示框架的版本 显然,它们都是最新的。 我的测试课: 创建一个实体实例,然后调用c
-ZJ 以下是我在Application.Properties中的数据源设置: