wordpress商城网站,微信输入法使用方法,网站开发背景意义,成都网站设计 创新互联事务四大特性与隔离级别 mysql事务的概念事务的属性事务控制语句转账示例 并发事务引发的问题脏读脏读场景 不可重复读幻读幻读场景 事务的隔离级别读未提交读已提交可重复读#xff08;MySQL默认#xff09; 总结 mysql事务的概念 事务就是一组操作的集合#xff0c;他是一… 事务四大特性与隔离级别 mysql事务的概念事务的属性事务控制语句转账示例 并发事务引发的问题脏读脏读场景 不可重复读幻读幻读场景 事务的隔离级别读未提交读已提交可重复读MySQL默认 总结 mysql事务的概念 事务就是一组操作的集合他是一个不可分割的整体事务会把所有的操作作为一个整体一起向系统提交或撤销操作。 事务的属性
原子性Atomicity一致性Consistency隔离性Isolation持久性Durability
事务控制语句
查看/设置事务提交
START TRANSACTION;提交一个事务
COMMIT;回滚一个事务
ROLLBACK;1为自动提交0位手动提交。 msyql默认为自动提交需要手动设置为手动提交。 执行成功时进行commit提交事务程序出时是进行回滚事务 转账示例
-- 关闭自动提交
SET AUTOCOMMIT 0;-- 开始事务
START TRANSACTION;-- 查询张三和李四的余额
SELECT balance INTO zhangsan_balance FROM accounts WHERE name 张三;
SELECT balance INTO lisi_balance FROM accounts WHERE name 李四;-- 如果张三的余额足够进行转账操作
IF zhangsan_balance 1000 THEN-- 更新张三和李四的余额UPDATE accounts SET balance balance - 1000 WHERE name 张三;UPDATE accounts SET balance balance 1000 WHERE name 李四;-- 提交事务COMMIT;SELECT 转账成功;
ELSE-- 回滚事务ROLLBACK;SELECT 转账失败张三余额不足;
END IF;-- 开启自动提交
SET AUTOCOMMIT 1;
并发事务引发的问题 脏读 脏读Dirty Read是指一个事务在读取另一个未提交的事务所做的修改时产生不一致的结果。具体来说当一个事务读取了另一个事务未提交的数据然后这个未提交的数据被回滚了那么读取到的数据就是脏数据因为它实际上不应该存在于数据库中。 脏读场景 假设有两个用户A 和 B。用户 A 有 1000 元用户 B 有 2000 元。现在 A 从自己的账户中转账 500 元到 B 的账户。 初始状态 用户 A 的账户余额为 1000 元。 用户 B 的账户余额为 2000 元。 转账操作 用户 A 开始一个事务从自己的账户中扣除 500 元。 用户 B 开始一个事务将 500 元存入自己的账户。 脏读 用户 B 在事务中读取自己的账户余额发现账户余额变成了 2500 元未提交的转账操作。 用户 A 的转账操作因为某种原因失败并回滚了。 结果 用户 B 实际上没有收到任何转账但是由于脏读他错误地读取到了自己账户的余额为 2500 元这是一个不一致的状态。 不可重复读 事务A在第一步查询了id为1的数据然后事务B修改id为1的数据并且提交了数据然后事务A在第三步又查询了id为1的数据发现两次查询的数据不一致。 幻读 幻读Phantom Read是并发事务可能遇到的另一种问题也涉及到事务隔离性。幻读场景指的是在一个事务中多次执行相同的查询但在不同的查询中返回了不同数量的行。 幻读场景
事务T1执行了一个查询返回了一组满足某个条件的行。事务T2插入了一些新的行这些行也满足了T1查询中的条件并且提交了事务。事务T1再次执行相同的查询但这次返回的结果集比之前多了新插入的行导致得到了不一致的结果。
事务的隔离级别 对号表示问题会出现X白表示问题已解决。 串行化·安全性高效率低。 读未提交效率最高但是安全性最低 读未提交
-- 事务T1
START TRANSACTION;-- 事务T2
START TRANSACTION;-- T2更新了某行数据
UPDATE table_name SET column1 new_value WHERE condition;-- T1读取T2尚未提交的数据
SELECT * FROM table_name WHERE condition;-- T2提交
COMMIT;-- T1继续
-- T1读取了已提交的数据
SELECT * FROM table_name WHERE condition;-- T1提交
COMMIT;
读已提交
-- 事务T1
START TRANSACTION;-- 事务T2
START TRANSACTION;-- T2更新了某行数据
UPDATE table_name SET column1 new_value WHERE condition;-- T2提交
COMMIT;-- T1读取T2已提交的数据
SELECT * FROM table_name WHERE condition;-- T1提交
COMMIT;
可重复读MySQL默认
-- 事务T1
START TRANSACTION;-- 事务T2
START TRANSACTION;-- T2更新了某行数据
UPDATE table_name SET column1 new_value WHERE condition;-- T2提交
COMMIT;-- T1再次读取T2修改的数据但是在可重复读级别下T1看到的数据仍然是之前启动事务时的快照数据
SELECT * FROM table_name WHERE condition;-- T1提交
COMMIT;
总结