Web services 服务@事务异常转换
我有一个web服务,其操作如下Web services 服务@事务异常转换,web-services,cxf,aop,spring-transactions,Web Services,Cxf,Aop,Spring Transactions,我有一个web服务,其操作如下 public Result checkout(String id) throws LockException; 实施方式如下: @Transactional public Result checkout(String id) throws LockException { someDao.acquireLock(id); // ConstraintViolationException might be thrown on commit Data d
public Result checkout(String id) throws LockException;
实施方式如下:
@Transactional
public Result checkout(String id) throws LockException {
someDao.acquireLock(id); // ConstraintViolationException might be thrown on commit
Data data = otherDao.find(id);
return convert(data);
}
我的问题是锁定只能在事务提交时失败,而事务提交发生在我的服务方法之外,因此我没有机会将ConstraintViolationException
转换为我的自定义LockException
选择1
建议的一个选项是将服务委托给另一个@Transactional方法。例如
public Result checkout(String id) throws LockException {
try {
return someInternalService.checkout(id);
}
catch (ConstraintViolationException ex) {
throw new LockException();
}
}
...
public class SomeInternalService {
@Transactional
public Result checkout(String id) {
someDao.acquireLock(id);
Data data = otherDao.find(id);
return convert(data);
}
}
我的问题是:
- 对于外部服务尚未使用的内部服务,没有合理的名称,因为它们基本上在做相同的事情。这似乎是一个糟糕设计的指标
- 如果我想在另一个地方重用某个InternalService.checkout,那么这个契约是错误的,因为无论使用它的是什么,都会得到一个ConstraintViolationException
checkout
需要声明它抛出LockException
供客户端使用,但实际的服务永远不会抛出它,而是由通知抛出。没有什么可以阻止将来有人从界面中删除抛出锁异常,因为它似乎不正确
而且,这种方法更难测试。如果不创建spring上下文并在测试期间使用AOP,我无法编写JUnit测试来验证抛出的异常
选择3
在签出中使用手动事务管理
?我真的不喜欢这样,因为应用程序中的所有其他内容都使用声明式样式
有人知道处理这种情况的正确方法吗?没有正确的方法
您还有几个选择:
使DAO具有事务性—这不是很好,但可以工作
创建一个包装服务(称为Facade),其工作是围绕您提到的事务性服务进行异常处理/包装,这是一个明确的关注点分离,可以与真正的低级服务共享方法名称