如何在Spring MVC mysql DAO连接中使用try catch?

时间:2015-03-10 12:39:22

标签: java mysql database spring spring-mvc

我正在学习Spring MVC Web开发并使用mysql数据库。我找到了一个很好的例子,在here春天使用DAO连接mysql。

我测试代码时运行得很好。我很想更进一步,我想到了SQL连接异常。所以我试着访问sql测试页面而没有运行mysql,我在该页面上得到500错误。我看到的例外是

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

所以有人可以告诉我,如果它是生产网站,我应该把try{} catch(){}块放在哪里以避免这种情况?

我尝试将这些代码放在MVC配置类

   @Bean
    public DataSource getDataSource() {


        private DriverManagerDataSource dataSource;

        try{

        dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/contactdb");
        dataSource.setUsername("root");
        dataSource.setPassword("P@ssw0rd");
          }
         catch(Exception e){
          System.out.println("Connection error.");
          System.exit(0); 

        }
        finally{
         return dataSource;
         }
    }

但它没有用,所以任何人都可以帮助我并告诉我如何将它放在try catch块或更好的解决方案中以避免这种错误?

提前谢谢。

1 个答案:

答案 0 :(得分:1)

由于您使用的是Spring,因此您应该阅读:

问题不在于创建数据源本身。当Spring定义这个bean时,很可能它甚至都没有尝试创建连接。所以,这里不会失败。另外,只是吞下异常并不会帮助你,如果你按照你的方法尝试使用数据源,你会在以后得到NullPointerException。

以下代码可能会失败,无论您何时尝试使用数据源访问数据库。根据您实现存储库/数据访问层的方式,这可能甚至不会发生在您自己的代码中,而是发生在Spring代码中的其他地方。

您需要的是在服务层中实现每次访问数据访问层操作时可能会因以下原因而失败的原因:数据库已关闭,连接超时,违反约束等。我们不能指望这一切都会成功。所以,为最坏的情况做好准备。

这是您可以定义尝试捕获策略的地方。这是最好的地方,因为你有足够的信息可以解决什么可能出错,你可以处理它或将异常包装到更多的上下文异常中,这将有助于以后诊断和解决问题

该地方的一个策略是重试您的交易。由于您已经在使用Spring,因此可以考虑spring-retry之类的内容。

某些异常会立即重试。例如,连接超时,或者数据库暂时关闭等。其他类型的异常没有任何意义重试,例如数据库约束违规异常。无论你为这些后者中的任何一个重试事务失败多少次,它总是会失败。因此,使用Spring重试,您可以轻松配置这些类型的东西。

您可以阅读Spring如何为您的数据访问层提供consistent exception hierarchy,从而大大简化此任务。

或者,当您无法阻止事务失败时,您必须抛出上下文异常,尽可能详细地说明出现了什么问题。理想情况下,您应该使用日志记录,以便稍后确定发生了什么。

例如,在部门服务层中:

@Autowire
DepartmentDao deptDao;

@Transactional(readOnly = true)
public Department getDepartment(Integer id) {
  try {
     return deptDao.findDepartmentById(id);
  } catch(RuntimeException rte) {
    throw new ServiceOperationException("Failed to retrieve department " + id, rte); 
  }
}

这种异常将导致更多的上下文失败原因,异常堆栈跟踪将包含返回到实际失败的地方的所有路径,但跟踪中的第一个异常始终指向代码中的位置你的交易失败了。

在控制器层,Spring具有允许您定义your own exception handlers的功能。这样,您可以决定在发生上下文异常时返回客户端的内容。