事務(wù): 是一個完整的業(yè)務(wù)流程,可以有效的防止數(shù)據(jù)丟失
事務(wù)特性: 原子性 一致性 隔離性 持久性
使用事務(wù)的方法:
1.關(guān)閉自動提交,開啟事務(wù):通過 connection.setAutoCommit(false) 關(guān)閉自動提交,手動控制事務(wù)。
2.提交事務(wù):通過connection.commit() 提交事務(wù),使所有操作生效
3.異常處理:如果發(fā)生 SQLException,捕獲異常并使用connection.rollback(); 回滾事務(wù),確保數(shù)據(jù)一致性。
示例代碼
假設(shè)我們有兩個表:accounts 和 transactions。accounts 表存儲賬戶信息,transactions 表存儲交易記錄。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JdbcTransactionExample {
// 數(shù)據(jù)庫連接信息
private static final String URL = "jdbc:mysql://localhost:3306/your_database";
private static final String USER = "your_username";
private static final String PASSWORD = "your_password";
public static void main(String[] args) {
Connection connection = null;
PreparedStatement updateAccountStmt = null;
PreparedStatement insertTransactionStmt = null;
try {
// 1. 加載數(shù)據(jù)庫驅(qū)動
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 建立數(shù)據(jù)庫連接
connection = DriverManager.getConnection(URL, USER, PASSWORD);
// 3. 關(guān)閉自動提交,開啟事務(wù)
connection.setAutoCommit(false);
// 4. 創(chuàng)建 PreparedStatement 對象
String updateAccountSql = "UPDATE accounts SET balance = balance + ? WHERE id = ?";
String insertTransactionSql = "INSERT INTO transactions (account_id, amount, transaction_type) VALUES (?, ?, ?)";
updateAccountStmt = connection.prepareStatement(updateAccountSql);
insertTransactionStmt = connection.prepareStatement(insertTransactionSql);
// 5. 執(zhí)行轉(zhuǎn)賬操作
int fromAccountId = 1; // 轉(zhuǎn)出賬戶ID
int toAccountId = 2; // 轉(zhuǎn)入賬戶ID
double amount = 100.00; // 轉(zhuǎn)賬金額
// 從轉(zhuǎn)出賬戶扣款
updateAccountStmt.setDouble(1, -amount);
updateAccountStmt.setInt(2, fromAccountId);
updateAccountStmt.executeUpdate();
// 向轉(zhuǎn)入賬戶加款
updateAccountStmt.setDouble(1, amount);
updateAccountStmt.setInt(2, toAccountId);
updateAccountStmt.executeUpdate();
// 插入交易記錄
insertTransactionStmt.setInt(1, fromAccountId);
insertTransactionStmt.setDouble(2, -amount);
insertTransactionStmt.setString(3, "DEBIT");
insertTransactionStmt.executeUpdate();
insertTransactionStmt.setInt(1, toAccountId);
insertTransactionStmt.setDouble(2, amount);
insertTransactionStmt.setString(3, "CREDIT");
insertTransactionStmt.executeUpdate();
// 6. 提交事務(wù)
connection.commit();
System.out.println("Transaction completed successfully.");
} catch (ClassNotFoundException e) {
System.err.println("Database driver not found.");
e.printStackTrace();
} catch (SQLException e) {
System.err.println("SQL error occurred. Rolling back transaction.");
e.printStackTrace();
try {
if (connection != null) {
connection.rollback(); // 回滾事務(wù)
}
} catch (SQLException ex) {
ex.printStackTrace();
}
} finally {
// 7. 關(guān)閉資源
try {
if (updateAccountStmt != null) {
updateAccountStmt.close();
}
if (insertTransactionStmt != null) {
insertTransactionStmt.close();
}
if (connection != null) {
connection.setAutoCommit(true); // 恢復(fù)自動提交
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}