Mysql基础(③事务)
假设银行账户表 account
初始数据如下(两个人的余额):
name | balance(余额) |
---|---|
张三 | 1000 元 |
李四 | 2000 元 |
场景 1:正常提交事务(转账成功)
步骤拆解:
开启事务
告诉数据库:“接下来的操作要打包成一个整体,要么全成,要么全败”
BEGIN; -- 开启事务
执行转账操作
张三给李四转 300 元,所以张三的余额要减 300,李四的余额要加 300
-- 张三余额从1000→700(扣300)
UPDATE account SET balance = 700 WHERE name = '张三';-- 李四余额从2000→2300(加300)
UPDATE account SET balance = 2300 WHERE name = '李四';
此时查询数据(未提交前):
SELECT * FROM account;
-- +------+---------+
-- | name | balance |
-- +------+---------+
-- | 张三 | 700 | -- 临时修改,未最终生效
-- | 李四 | 2300 | -- 临时修改,未最终生效
-- +------+---------+
注意:这一步的修改只是 “临时存在内存中”,还没写到磁盘的实际数据文件里。
确认无误,提交事务
告诉数据库:“所有操作都没问题,把修改永久保存吧”
COMMIT; -- 提交事务,修改永久生效
最终结果
再次查询,数据已永久改变:
SELECT * FROM account;
-- +------+---------+
-- | name | balance |
-- +------+---------+
-- | 张三 | 700 | -- 最终余额
-- | 李四 | 2300 | -- 最终余额
-- +------+---------+
场景 2:出错回滚事务(转账失败,数据恢复)
步骤拆解:
开启事务
BEGIN; -- 开启事务
执行部分操作后出错
先扣张三的钱(300 元):
UPDATE account SET balance = 700 WHERE name = '张三'; -- 张三从1000→700
此时查询(未提交前):
SELECT * FROM account;
-- +------+---------+
-- | name | balance |
-- +------+---------+
-- | 张三 | 700 | -- 临时扣钱
-- | 李四 | 2000 | -- 还没加钱
-- +------+---------+
突然出错:比如网络断了、数据库崩溃了,或者执行加钱操作时输入错误(如写成 balance = 200 而不是 2300)。
回滚事务
发现错误后,告诉数据库:“刚才的操作有问题,全部撤销吧”
ROLLBACK; -- 回滚事务,撤销所有未提交的修改
最终结果
数据恢复到事务开始前的状态,就像没执行过任何操作:
SELECT * FROM account;
-- +------+---------+
-- | name | balance |
-- +------+---------+
-- | 张三 | 1000 | -- 扣的钱退回来了
-- | 李四 | 2000 | -- 没加钱,保持原样
-- +------+---------+
提交(COMMIT):就像 “确认转账”,所有操作永久生效,不能再撤销。
回滚(ROLLBACK):就像 “取消转账”,所有未确认的操作全部作废,数据回到最初状态。
事务的核心:要么一步到位(提交),要么彻底不算(回滚),绝对不会出现 “张三的钱扣了,李四的钱没加上” 这种混乱情况。