在Spring JPA Web应用程序中构建可靠性



我正在努力寻找一种解决方案,为我们的网络应用程序构建可靠性。计划是,如果网络连接/数据库连接丢失,则将sql和数据一起转储。在当前的实现中,我们有Rest控制器、Service、DAO。DAO抛出PersistenceExcetpion,并将其传播到Controller层。

示例代码:

public MyDAOClass {
    public void save(Object object) {
        try {
            entityManager.persist(object);
        } catch (PersistenceException e) {
            throw new DBException("Error occurred in save", e);
        }
    }
}

DBException是一个运行时异常。

现在真正的问题来了。其中一位队友建议有自定义异常,例如InsertException, UpdateException等。如果我们遇到这些异常中的任何一个,我们就会知道对该实体执行了哪个操作,这样它就可以作为适当的sql保存到文件中。

例如。假设代码未能保存Employee实体。这将抛出InsertException,并将在文件中创建一个条目作为该实体的insert sql语句。insert into employeee values ('firstname','lastname');

对我来说,在连接丢失时实现sql文件创建的想法似乎并不像实现上述内容那么简单。

我提出的问题是1) 当在服务方法中执行多个操作(如插入、更新、删除的任何组合)时,您如何处理?2) 不同的例外情况如何?我的意思是,PerisistenceException的原因可能是约束失败、找不到实体等,而不仅仅是连接问题。

是否有任何方法可以实现上述场景,同时考虑所有不同的条件。

谢谢。

更新:根据chrylis的评论。我本应该把这个问题加进去的。这是一个在不同零售店本地运行的网络应用程序。而且应用程序不能停机,所以如果出现任何连接问题,应用程序应该继续工作。该文件稍后将与中央数据库服务器同步。

使用spring,您可以使用Hibernate ORM将数据存储到数据库中。如果在任何请求过程中发生异常,则hibernate将回滚该异常。这取决于你把@Transnational注释放在哪里。

我们使用一个处理事务的服务层。因此,如果数据库操作或任何其他操作在服务层失败并引发异常,则hibernate会自动回滚事务。然后,我们使用spring异常解析程序来处理任何异常,并在日志和用户中写入自定义错误。我想你也可以将异常存储在另一个数据库中,如果这很有趣的话,我认为记录它们就足够了。

这篇文章教你更多关于一般异常处理的知识。

这是我们的异常解析程序。

import ...
@ControllerAdvice
public class SpringExceptionResolver {
    Logger logger = LoggerFactory.getLogger("com.realitylabs.event.controller.RecoverController"); 

    @ExceptionHandler({CorruptedSessionUserException.class})
    @ResponseBody
    @ResponseStatus(value=HttpStatus.FORBIDDEN)
    public ErrorObject userNotFoundExceptionHandler() {
      // Handle exception
      // log using the logger.
      // We usually return an error object in JSON so that we can show custom    // error messages.
    }

}

以下是服务的外观。我们通常从控制器呼叫我们的服务。如果来自控制器的异常被抛出,建议将处理它。

import ...
@Service(value="ObjectService")
@Transactional
public class ObjectServiceImpl implements ObjectService {
  @Autowired
  private ObjectDAO objectDAO;
  @Override
  public Object get(int id) {
    Object o = objectDAO.get(id);
    Hibernate.initialize(o.getVoters());
    return o;
  }
}

我希望这能有所帮助。

最新更新