简体   繁体   中英

How to use try catch in Spring MVC mysql DAO connection?

I am learning Spring MVC web development and using mysql database for it. I found a good example to connect with mysql using DAO in spring at here .

It was running perfectly when I tested my codes. I was curious to go more further and I thought about SQL Connection exception. So I tried to visit sql test page without mysql running and I got 500 error on that page. And Exception that I saw was

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

So can anyone tell me where should I put try{} catch(){} block to avoid this situation if it is production website?

I tried my self putting these codes in MVC Configuration class

   @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;
         }
    }

but it did not work so can anyone help me and tell me how can I put it in try catch block or some better solution to avoid this kind of errors?

Thank you in advance.

Since you are using Spring, you should probably read:

The problem is not in the creation of the data source itself. When Spring defines this bean, most likely it does not even attempt to create a connection. So, it does not fail here. Plus just swallowing the exception won't help you, you would get NullPointerException later on when you try to use the datasource if you follow your approach.

You code probably fails later on, wherever you are trying to use the data source to access the database. Depending on how you are implementing your repository/data access layer, this may not even be happening in your own code but somewhere else in Spring code.

What you need is to realize that in the service layer, every time you access a data access layer operation that might fail for a number a reasons: the database is down, a connection time out, a constraint violation, etc. You can't simply expect this will always succeed. So, prepare for the worst.

That's the place where you can probably define a try-catch strategy. And that's the best place to do it because there you have enough information of what exactly may have gone wrong and you can either handle it or wrap the exception into a more contextual exception that will help later to diagnose and solve the problem.

One strategy in that place is to retry your transaction. Since you are already using Spring you could consider something like spring-retry .

There are certain kind of exceptions that are prompt to retries. For instance a connection time out, or if the database was temporarily down, etc. Other type of exceptions don't make any sense to retry, like for instance a database constraint violation exception. No matter how many times you retry a transaction failing for any of these latter, it will always fail. So with Spring retry you can easily configure those kinds of things.

You can read how Spring provides a consistent exception hierarchy for your data access layer that can greatly simplify this task.

Alternatively, when there is nothing you can do to prevent that a transaction fails then you must throw an contextual exception giving as much detail as possible of what went wrong. Ideally you should be using logging so that it can be later determined what happened.

For instance, in a department service layer:

@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); 
  }
}

This way the exception will have a more contextual cause of failure, the exception stack trace will contain all the trail back to the place where it actually failed, but the first exception in the trace always points to the place in your code where your transaction failed.

At the controller layer, Spring has features that let you define your own exception handlers . That way you can decide what to return to the client in the event of one your contextual exceptions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM