Generally, for any class that implements Closeable (and thus has a close() method),
you should make sure it gets closed when you are done with it. That applies to the CallableStatement cs, the ResultSet rs,
and the Connection conn. It's good programming practice to get in the habit of
always making sure these things get closed when you're done - and try-with-ressources is the easiest and most reliable way to do this. In this case, that's like this:
Each of those try statements is ensuring that when you leave that try statment, the associated object (conn / cs / rs) will be closed, no matter what.
What happens if you neglect to do this? Well, in many cases, not much. Often the thing that you forgot to close will get closed automatically later on, e.g. when your program exits. But
sometimes, it won't get closed quickly enough, and that can cause problems. You might later be trying to do a database operation, and you find you can't connect because your DB can't support that many simultaneous connections, or users, or something... and you say,
what simultaneous users? And it's actually because you're doing something repeatedly in a loop and leaving resources unclosed, and the DB is freaking out because it can't do that many things at once, except it doesn't really need to do so many things at once - you just need to tell the db that you're done with those objects, when you're done with them. Which is what the close() method is for.
If you
do get problems, they're often rather confusing and mysterious, occurring sometime
after you failed to close something. So it can be a pain to track down the cause. It's generally much easier to just get in the habit of always closing the things that are Closeable. Which is what try-with-resources is very, very good at.