以下ã¯ã€Javaã§ã®ç°¡å˜ãªéŠ€è¡Œå–引プãƒã‚°ãƒ©ãƒ ã®è§£ç”例ã¨è§£èª¬ã§ã™ã€‚ã“ã®ä¾‹ã§ã¯ã€é€é‡‘å…ƒã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«ååˆ†ãªæ®‹é«˜ãŒãªã„å ´åˆã«ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯ã—ã€ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã—ã¾ã™ã€‚データベースã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯ try-with-resources 文を使用ã—ã¦ç¢ºå®Ÿã«ã‚¯ãƒãƒ¼ã‚ºã•れるよã†ã«ã—ã¾ã™ã€‚
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
// カスタム例外クラス
class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}
public class BankTransactionExample {
private static final String DB_URL = "jdbc:mysql://localhost:3306/bank";
private static final String DB_USER = "your_username";
private static final String DB_PASSWORD = "your_password";
// 銀行å–引メソッド
public static void transferFunds(int fromAccount, int toAccount, double amount) throws SQLException, InsufficientFundsException {
// データベースã¸ã®æŽ¥ç¶š
try (Connection connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
// トランザクションã®é–‹å§‹
connection.setAutoCommit(false);
// é€é‡‘å…ƒã®æ®‹é«˜å–å¾—
double balance = getAccountBalance(connection, fromAccount);
// 残高ãŒå分ã‹ç¢ºèª
if (balance < amount) {
// 残高ä¸è¶³ã®å ´åˆã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯ã—例外をスãƒãƒ¼
connection.rollback();
throw new InsufficientFundsException("é€é‡‘å…ƒã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®æ®‹é«˜ãŒä¸è¶³ã—ã¦ã„ã¾ã™ã€‚");
}
// é€é‡‘元アカウントã‹ã‚‰å¼•ãè½ã¨ã—
updateAccountBalance(connection, fromAccount, balance - amount);
// é€é‡‘先アカウントã«å…¥é‡‘
updateAccountBalance(connection, toAccount, getAccountBalance(connection, toAccount) + amount);
// トランザクションをコミット
connection.commit();
}
}
// 指定ã•れãŸã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®æ®‹é«˜ã‚’å–å¾—ã™ã‚‹ãƒ¡ã‚½ãƒƒãƒ‰
private static double getAccountBalance(Connection connection, int accountNumber) throws SQLException {
String query = "SELECT balance FROM accounts WHERE account_number = ?";
try (PreparedStatement preparedStatement = connection.prepareStatement(query)) {
preparedStatement.setInt(1, accountNumber);
var resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
return resultSet.getDouble("balance");
}
throw new SQLException("アカウントãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。");
}
}
// 指定ã•れãŸã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®æ®‹é«˜ã‚’æ›´æ–°ã™ã‚‹ãƒ¡ã‚½ãƒƒãƒ‰
private static void updateAccountBalance(Connection connection, int accountNumber, double newBalance) throws SQLException {
String query = "UPDATE accounts SET balance = ? WHERE account_number = ?";
try (PreparedStatement preparedStatement = connection.prepareStatement(query)) {
preparedStatement.setDouble(1, newBalance);
preparedStatement.setInt(2, accountNumber);
int affectedRows = preparedStatement.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("アカウントãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。");
}
}
}
public static void main(String[] args) {
try {
// ユーザーãŒã‚¢ã‚«ã‚¦ãƒ³ãƒˆé–“ã§è³‡é‡‘を移動ã™ã‚‹ä¾‹
transferFunds(123456, 789012, 1000.0);
System.out.println("å–å¼•ãŒæˆåŠŸã—ã¾ã—ãŸã€‚");
} catch (SQLException | InsufficientFundsException e) {
System.err.println("å–引エラー: " + e.getMessage());
}
}
}
ã“ã®ä¾‹ã§ã¯ã€InsufficientFundsException ãŒé€é‡‘å…ƒã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®æ®‹é«˜ä¸è¶³æ™‚ã«ã‚¹ãƒãƒ¼ã•れã¾ã™ã€‚トランザクションã®ç®¡ç†ãŒé‡è¦ã§ã‚ã‚Šã€æ®‹é«˜ãŒå分ã§ãªã„å ´åˆã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯ã—ã€å¤‰æ›´ã‚’å…ƒã«æˆ»ã—ã¾ã™ã€‚
トランザクションã¨ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯
1. ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®æ¦‚è¦
トランザクションã¯ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®ä¸€é€£ã®æ“作をæ„味ã—ã¾ã™ã€‚ã“ã‚Œã‚‰ã®æ“作ã¯ã€æˆåŠŸã™ã‚‹ã‹å¤±æ•—ã™ã‚‹ã‹ã®ã„ãšã‚Œã‹ã§ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³å…¨ä½“ãŒåŽŸåæ€§ã‚’æŒã¡ã¾ã™ã€‚åŽŸåæ€§ã¨ã¯ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒå…¨ä½“ã¨ã—ã¦æˆåŠŸã™ã‚‹ã‹ã€å…¨ä½“ã¨ã—ã¦å¤±æ•—ã™ã‚‹ã‹ã®ã„ãšã‚Œã‹ã§ã‚ã‚‹ã“ã¨ã‚’指ã—ã¾ã™ã€‚åŽŸåæ€§ãŒä¿ãŸã‚Œãªã„å ´åˆã€é€”ä¸ã§ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¦ã‚‚トランザクションã®ä¸€éƒ¨ãŒãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«å¤‰æ›´ã‚’åŠ ãˆãŸå¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚
2. トランザクションã®ç®¡ç†
トランザクションã®ç®¡ç†ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹æŽ¥ç¶šã‚’使用ã—ã¦è¡Œã„ã¾ã™ã€‚トランザクションã¯é€šå¸¸ã€ä»¥ä¸‹ã®æ‰‹é †ã§å®Ÿè¡Œã•れã¾ã™ã€‚
- トランザクションã®é–‹å§‹: ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³å†…ã®æ“作ãŒå§‹ã¾ã‚‹ã“ã¨ã‚’データベースã«é€šçŸ¥ã—ã¾ã™ã€‚ã“れã«ã‚ˆã‚Šã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒå§‹ã¾ã‚Šã€ãれã«é–¢é€£ã™ã‚‹æ“作ãŒåŽŸåçš„ã«ãªã‚Šã¾ã™ã€‚
- トランザクションã®ã‚³ãƒŸãƒƒãƒˆ: ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒæˆåŠŸã—ãŸå ´åˆã€å¤‰æ›´ã‚’データベースã«ç¢ºå®šã•ã›ã¾ã™ã€‚ã“れã«ã‚ˆã‚Šã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³å†…ã§è¡Œã‚れãŸå¤‰æ›´ãŒãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«æ°¸ç¶šçš„ã«åæ˜ ã•れã¾ã™ã€‚
- トランザクションã®ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯: トランザクションãŒå¤±æ•—ã—ãŸå ´åˆã€å¤‰æ›´ã‚’å–り消ã—ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³å†…ã§è¡Œã‚れãŸã™ã¹ã¦ã®å¤‰æ›´ã‚’å…ƒã«æˆ»ã—ã¾ã™ã€‚
3. トランザクションã¨ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯ã®é‡è¦æ€§
トランザクションã¨ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®ä¸€è²«æ€§ã‚’ä¿ã¤ãŸã‚ã«éžå¸¸ã«é‡è¦ã§ã™ã€‚トランザクション内ã§ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãŸå ´åˆã€ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯ã‚’行ã†ã“ã¨ã§ã€å¤‰æ›´ã‚’å–り消ã—ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’å‰ã®çŠ¶æ…‹ã«æˆ»ã™ã“ã¨ãŒã§ãã¾ã™ã€‚ã“れã«ã‚ˆã‚Šã€ãƒ‡ãƒ¼ã‚¿ã®æ•´åˆæ€§ãŒä¿ãŸã‚Œã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãŒä¿¡é ¼æ€§ã‚’ç¶æŒã—ã¾ã™ã€‚
4. サンプルプãƒã‚°ãƒ©ãƒ ã®è§£èª¬
サンプルプãƒã‚°ãƒ©ãƒ ã§ã¯ã€transferFunds メソッド内ã§ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒé–‹å§‹ã•ã‚Œã€æˆåŠŸã™ã‚‹ã‹å¤±æ•—ã™ã‚‹ã‹ãŒåˆ¤æ–ã•れã¦ã„ã¾ã™ã€‚残高ä¸è¶³ã®å ´åˆã€InsufficientFundsException ãŒã‚¹ãƒãƒ¼ã•れã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒãƒãƒ¼ãƒ«ãƒãƒƒã‚¯ã•れã¾ã™ã€‚ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯ connection.rollback() ã§è¡Œã„ã¾ã™ã€‚
try (Connection connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
// トランザクションã®é–‹å§‹
connection.setAutoCommit(false);
// é€é‡‘å…ƒã®æ®‹é«˜å–å¾—
double balance = getAccountBalance(connection, fromAccount);
// 残高ãŒå分ã‹ç¢ºèª
if (balance < amount) {
// 残高ä¸è¶³ã®å ´åˆã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯ã—例外をスãƒãƒ¼
connection.rollback();
throw new InsufficientFundsException("é€é‡‘å…ƒã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®æ®‹é«˜ãŒä¸è¶³ã—ã¦ã„ã¾ã™ã€‚");
}
// ...(以下略)
// トランザクションをコミット
connection.commit();
}
ã“ã®ã‚ˆã†ã«ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¨ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯ã‚’使用ã™ã‚‹ã“ã¨ã§ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®ä¸€è²«æ€§ã‚’確ä¿ã—ã€ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãŸå ´åˆã«é©åˆ‡ã«å¯¾å‡¦ã§ãã¾ã™ã€‚
トランザクションã¨ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹å‡¦ç†ã«ãŠã„ã¦æ¬ ã‹ã›ãªã„概念ã§ã‚りã€ãƒ‡ãƒ¼ã‚¿ã®æ•´åˆæ€§ã‚„ä¿¡é ¼æ€§ã‚’ç¢ºä¿ã™ã‚‹ãŸã‚ã«é‡è¦ãªå½¹å‰²ã‚’æžœãŸã—ã¾ã™ã€‚トランザクションã¯ä¸€é€£ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹æ“作を原åçš„ã«ã¾ã¨ã‚ã€å…¨ä½“ãŒæˆåŠŸã™ã‚‹ã‹å¤±æ•—ã™ã‚‹ã‹ã‚’ä¿è¨¼ã—ã¾ã™ã€‚ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³å†…ã§ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãŸå ´åˆã«å¤‰æ›´ã‚’å–り消ã—ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’å‰ã®çŠ¶æ…‹ã«æˆ»ã—ã¾ã™ã€‚
データベースå–引ã«ãŠã„ã¦ã¯ã€ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚‹ãŸã‚ã€ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¨ãƒãƒ¼ãƒ«ãƒãƒƒã‚¯ã®ç†è§£ã¨é©åˆ‡ãªåˆ©ç”¨ãŒä¸å¯æ¬ ã§ã™ã€‚ã“れã«ã‚ˆã‚Šã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãŒä¸€è²«æ€§ã‚’ä¿ã¡ã€ã‚·ã‚¹ãƒ†ãƒ ãŒä¿¡é ¼æ€§ã‚’確ä¿ã§ãã¾ã™ã€‚
é©åˆ‡ãªãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ç®¡ç†ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹å‡¦ç†ã®å®‰å®šæ€§ã¨ä¿¡é ¼æ€§ã«ç›´çµã—ã€é–‹ç™ºè€…ãŒã‚·ã‚¹ãƒ†ãƒ 全体ã®ä¸€è²«æ€§ã‚’ç¶æŒã§ãるよã†ã‚µãƒãƒ¼ãƒˆã—ã¾ã™ã€‚
「019 例外ã¨ä¾‹å¤–処ç†ã€å•題集リスト
🎯 実習ã§ç†è§£ã‚’æ·±ã‚よã†
ã“ã®å†…容ã«ã¤ã„ã¦JavaDrillã§å®Ÿéš›ã«æ‰‹ã‚’å‹•ã‹ã—ã¦å¦ç¿’ã§ãã¾ã™


コメント