MySQL - 5、トランザクションとロック操作

ユーザーとトランザクションという 2 つのテーブルを持つ単純なデータベースがあります。users テーブルはユーザー情報を格納するために使用され、transactions テーブルはトランザクション情報を格納するために使用されます。

まず、データベースとテーブルを作成します。

CREATE DATABASE IF NOT EXISTS my_database;

USE my_database;

CREATE TABLE IF NOT EXISTS users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(50) NOT NULL,
  balance DECIMAL(10, 2) NOT NULL DEFAULT 0
);

CREATE TABLE IF NOT EXISTS transactions (
  id INT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  amount DECIMAL(10, 2) NOT NULL,
  type ENUM('deposit', 'withdraw') NOT NULL,
  timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

いくつかのテスト データを挿入します。

INSERT INTO users (username, balance) VALUES
  ('lfsun-1', 1000.00),
  ('lfsun-2', 500.00),
  ('lfsun-4', 200.00);

次に、トランザクションを使用して送金操作をシミュレートします。100.00 の金額を lfsun-1 から lfsun-2 に転送するとします。

-- 开始事务
START TRANSACTION;

-- 更新 lfsun-1 的余额
UPDATE users
SET balance = balance - 100.00
WHERE username = 'lfsun-1';

-- 更新 lfsun-2 的余额
UPDATE users
SET balance = balance + 100.00
WHERE username = 'lfsun-2';

-- 向 transactions 表插入一条记录表示转账操作
INSERT INTO transactions (user_id, amount, type)
VALUES ((SELECT id FROM users WHERE username = 'lfsun-1'), 100.00, 'withdraw'),
       ((SELECT id FROM users WHERE username = 'lfsun-2'), 100.00, 'deposit');

-- 提交事务
COMMIT;

ここで、転送で問題が発生し、操作をロールバックする必要があるとします。

-- 开始事务
START TRANSACTION;

-- 更新 lfsun-1 的余额
UPDATE users
SET balance = balance - 100.00
WHERE username = 'lfsun-1';

-- 更新 lfsun-2 的余额
UPDATE users
SET balance = balance + 100.00
WHERE username = 'lfsun-2';

-- 向 transactions 表插入一条记录表示转账操作
INSERT INTO transactions (user_id, amount, type)
VALUES ((SELECT id FROM users WHERE username = 'lfsun-1'), 100.00, 'withdraw'),
       ((SELECT id FROM users WHERE username = 'lfsun-2'), 100.00, 'deposit');

-- 回滚事务
ROLLBACK;

場合によっては、よりきめ細かいトランザクション制御を実現するためにセーブポイント (SAVEPOINT) を使用することが必要になる場合があります。

-- 开始事务
START TRANSACTION;

-- 更新 lfsun-1的余额
UPDATE users SET balance = balance - 100.00 WHERE username = 'lfsun-1';

-- 保存点1
SAVEPOINT point1;

-- 更新 lfsun-2 的余额
UPDATE users SET balance = balance + 100.00 WHERE username = 'lfsun-2';

-- 向 transactions 表插入一条记录表示转账操作
INSERT INTO transactions (user_id, amount, type) VALUES
  ((SELECT id FROM users WHERE username = 'lfsun-1'), 100.00, 'withdraw'),
  ((SELECT id FROM users WHERE username = 'lfsun-2'), 100.00, 'deposit');

-- 发生错误,回滚到保存点1
ROLLBACK TO point1;

-- 提交事务
COMMIT;

最後に、テーブル ロックの使用法を示します (LOCK TABLES および UNLOCK TABLES)。

-- 锁定 users 表,防止其他会话对其进行修改
LOCK TABLES users WRITE;

-- 执行一些操作,例如更新或插入数据

-- 解锁 users 表
UNLOCK TABLES;

おすすめ

転載: blog.csdn.net/qq_43116031/article/details/131969553