JDBC(七) 事务控制

事务: 是一个完整的业务流程,可以有效的防止数据丢失
事务特性: 原子性 一致性 隔离性 持久性
使用事务的方法:

1.关闭自动提交,开启事务:通过 connection.setAutoCommit(false) 关闭自动提交,手动控制事务。
2.提交事务:通过connection.commit() 提交事务,使所有操作生效
3.异常处理:如果发生 SQLException,捕获异常并使用connection.rollback(); 回滚事务,确保数据一致性。

示例代码

假设我们有两个表:accounts 和 transactions。accounts 表存储账户信息,transactions 表存储交易记录。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JdbcTransactionExample {

    // 数据库连接信息
    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. 加载数据库驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 2. 建立数据库连接
            connection = DriverManager.getConnection(URL, USER, PASSWORD);

            // 3. 关闭自动提交,开启事务
            connection.setAutoCommit(false);

            // 4. 创建 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. 执行转账操作
            int fromAccountId = 1; // 转出账户ID
            int toAccountId = 2;   // 转入账户ID
            double amount = 100.00; // 转账金额

            // 从转出账户扣款
            updateAccountStmt.setDouble(1, -amount);
            updateAccountStmt.setInt(2, fromAccountId);
            updateAccountStmt.executeUpdate();

            // 向转入账户加款
            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. 提交事务
            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(); // 回滚事务
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        } finally {
            // 7. 关闭资源
            try {
                if (updateAccountStmt != null) {
                    updateAccountStmt.close();
                }
                if (insertTransactionStmt != null) {
                    insertTransactionStmt.close();
                }
                if (connection != null) {
                    connection.setAutoCommit(true); // 恢复自动提交
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 重点参考(翻译):https://www.marcobehler.com/guides/spring-transa...
    伊丽莎白2015阅读 4,652评论 0 0
  • 事务:是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么...
    鑫狗_ab53阅读 1,449评论 0 0
  • Junit是一个基于Java语言的单元测试框架。是白盒测试的一种技术。 ①测试方法上必须使用@Test进行修饰 ...
    一介星辰阅读 3,669评论 0 0
  • ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■↓↓↓↓↓↓↓↓↓ JDB...
    _Levi__阅读 3,150评论 1 0
  • 一、数据库事务 事务的ACID(acid)属性 1. 原子性(Atomicity)�原子性是指事务是一个不可分割的...
    leeqico阅读 2,615评论 0 0