중첩 할당
이를 더 잘 이해하기 위해 다음 예제를 보자.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DBStatementExample {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// JDBC 드라이버 로드
Class.forName("com.mysql.jdbc.Driver");
// MySQL 데이터베이스에 연결
String url = "jdbc:mysql://localhost:3306/mydatabase";
String username = "root";
String password = "mypassword";
connection = DriverManager.getConnection(url, username, password);
// Statement 생성
statement = connection.createStatement();
// SELECT 쿼리 실행
String query = "SELECT * FROM mytable";
resultSet = statement.executeQuery(query);
// 결과 처리
while (resultSet.next()) {
// 결과 가져오기
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
// 결과 처리
System.out.println(id + ", " + name);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (resultSet != null) {
resultSet.close(); // 할당된 ResultSet 해제
}
if (statement != null) {
statement.close(); // 할당된 Statement 해제
}
if (connection != null) {
connection.close(); // 할당된 데이터베이스 커넥션 해제
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
위 예제는 JDBC를 사용하여 MySQL 데이터베이스에 연결하고, SELECT 쿼리를 실행하는 코드이다.
JDBC 드라이버를 로드하고, DriverManager.getConnection() 메소드를 사용하여 MySQL 데이터베이스에 연결한다. 연결이 성공하면 connection 변수에 할당된다. 이후 connection.createStatement() 메소드를 사용하여 statement 변수에 Statement를 생성하고 statement.executeQuery() 메소드를 사용하여 SELECT 쿼리를 실행하고, 결과를 resultSet 변수에 할당한다. 이후 resultSet.next() 메소드를 사용하여 결과를 하나씩 가져오고, 각 결과를 처리하는 작업을 수행한다.
finally 블록에서는 할당된 리소스를 해제한다. ResultSet, Statement, Connection 변수에 할당된 리소스를 각각 close() 메소드를 리소스 할당 역순으로 호출하여 해제한다. 이렇게 함으로써 교착 (deadlock) 가능성이 줄인다.
Statement와 ResultSet이 먼저 해제되어 데이터베이스 연결이 끊어진 상태에서 리소스가 해제되기 때문에, 이후 다시 데이터베이스 연결을 사용할 수 없게 된다.
리소스 할당과 해제가 다른 스레드에서 이루어지는 경우
리소스를 할당한 스레드가 아닌 다른 스레드에서 리소스를 해제하는 경우, 데드락이 발생할 가능성이 있다.
리소스를 공유하는 경우
다수의 스레드가 하나의 리소스를 공유하는 경우, 리소스의 할당 및 해제 순서만으로는 데드락을 예방할 순 없다.
스레드 우선순위의 변경
스레드 우선순위를 변경하는 경우, 리소스의 할당 및 해제 순서만으로는 데드락을 예방할 수 없다.