数据库的事务

本文详细解释了数据库事务的ACID特性,探讨了不同隔离级别,并通过在线购物平台的购物过程展示了事务在SQL和Java代码中的应用。
摘要由CSDN通过智能技术生成

数据库的事务

事务的四个基本特性(ACID)

原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不完成,不会结束在中间某个环节。
一致性(Consistency):事务必须使数据库从一个一致的状态转移到另一个一致的状态。
隔离性(Isolation):并发执行的事务之间不会互相影响。
持久性(Durability):一旦事务提交,它对数据库的改变就是永久性的,即使系统发生故障也不会丢失。

事务的隔离级别

为了处理并发事务,数据库系统提供了不同的事务隔离级别,包括:

  • 读未提交(Read Uncommitted)
  • 读已提交(Read Committed)
  • 可重复读(Repeatable Read)
  • 串行化(Serializable)

场景描述

用户在在线购物平台上购买了一款商品,该操作涉及以下步骤:

  • 检查商品库存。
  • 更新用户购物车。
  • 创建订单。
  • 更新库存。
  • 扣款操作。

sql语句

START TRANSACTION;

-- 检查库存
SELECT stock FROM products WHERE id = ?;

-- 如果库存大于0,继续执行以下语句
UPDATE shopping_cart SET quantity = quantity + 1 WHERE user_id = ? AND product_id = ?;

INSERT INTO orders (user_id, product_id, quantity, total_price) VALUES (?, ?, ?, ?);

UPDATE products SET stock = stock - 1 WHERE id = ?;

UPDATE users SET balance = balance - ? WHERE id = ?;

COMMIT;

假设我们有一个在线购物平台的数据库,其中包含以下表:

  • products:存储商品信息,包含id, stock等字段。
  • shopping_cart:存储用户的购物车信息,包含user_id, product_id, quantity等字段。
  • orders:存储订单信息,包含user_id, product_id, quantity, total_price等字段。
  • users:存储用户信息,包含id, balance等字段。

Java代码

import java.sql.*;

public class ShoppingCartService {
    private static final String URL = "jdbc:mysql://localhost:3306/shopping_platform";
    private static final String USER = "root";
    private static final String PASSWORD = "password";

    public void purchaseProduct(int userId, int productId, int productQuantity, double total_price) {
        Connection conn = null;
        PreparedStatement checkStockStmt = null;
        PreparedStatement updateCartStmt = null;
        PreparedStatement createOrderStmt = null;
        PreparedStatement updateStockStmt = null;
        PreparedStatement updateUserBalanceStmt = null;

        try {
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
            conn.setAutoCommit(false); // 开始事务

            // 检查库存
            checkStockStmt = conn.prepareStatement("SELECT stock FROM products WHERE id = ?");
            checkStockStmt.setInt(1, productId);
            ResultSet rs = checkStockStmt.executeQuery();
            if (!rs.next() || rs.getInt("stock") < 1) {
                throw new Exception("Product out of stock.");
            }

            // 更新购物车
            updateCartStmt = conn.prepareStatement("UPDATE shopping_cart SET quantity = quantity + 1 WHERE user_id = ? AND product_id = ?");
            updateCartStmt.setInt(1, userId);
            updateCartStmt.setInt(2, productId);
            updateCartStmt.executeUpdate();

            // 创建订单
            createOrderStmt = conn.prepareStatement("INSERT INTO orders (user_id, product_id, quantity, total_price) VALUES (?, ?, ?, ?)");
            createOrderStmt.setInt(1, userId);
            createOrderStmt.setInt(2, productId);
            createOrderStmt.setInt(3, productQuantity);
            createOrderStmt.setDouble(4, total_price);
            createOrderStmt.executeUpdate();

            // 更新库存
            updateStockStmt = conn.prepareStatement("UPDATE products SET stock = stock - 1 WHERE id = ?");
            updateStockStmt.setInt(1, productId);
            updateStockStmt.executeUpdate();

            // 扣款操作
            updateUserBalanceStmt = conn.prepareStatement("UPDATE users SET balance = balance - ? WHERE id = ?");
            updateUserBalanceStmt.setDouble(1, total_price);
            updateUserBalanceStmt.setInt(2, userId);
            updateUserBalanceStmt.executeUpdate();

            conn.commit(); // 提交事务
        } catch (Exception e) {
            if (conn != null) {
                try {
                    conn.rollback(); // 回滚事务
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
            e.printStackTrace();
        } finally {
            // 关闭资源
            try {
                if (checkStockStmt != null) checkStockStmt.close();
                if (updateCartStmt != null) updateCartStmt.close();
                if (createOrderStmt != null) createOrderStmt.close();
                if (updateStockStmt != null) updateStockStmt.close();
                if (updateUserBalanceStmt != null) updateUserBalanceStmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客李华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值