-- TCL /* Transcation Control Language 事务控制语言 事务:一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行 案例:转账 name 余额 麦克雷 1000 天使 1000 update 表 set 余额=500 where name = '麦克雷'; 意外 update 表 set 余额=1500 where name = '天使'; 出现错误或执行失败,则回滚。3 SHOW ENGINES 可以看到只有InnoDB支持事物 事物的ACID属性 1.Atomicity 原子性:一个事务是不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。 2.Consistency 一致性:事务必须使数据库从一个一致状态变成另一个一致性状态。例如转账完成后,余额的和还是2000。 3.Isolation 隔离性:一个事务的执行不受其他事务干扰,并发时各个事务之间不能互相干扰。 4.Druability 持久性:一个事务一旦被提交,它对数据库中的数据的改变是永久的。 */ -- 隐式事务:事务没有明显的开始和结束标记 如insert,update,delete语句 SHOW VARIABLES LIKE 'autocommit'; -- 默认是自动开启的 -- 显式事务:事务具有明显的开启和结束的标记 /* 前提:必须先设置自动提交功能为禁用 set autocommit = 0; 开启事务 可选 start transaction 编写sql语句(select insert update delete) 语句1, 语句2, ... 结束事务 commit 提交事务 rollback 回滚事务 */ CREATE TABLE IF NOT EXISTS account( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(20), balance DOUBLE ); INSERT INTO account(username,balance) VALUES ('麦克雷',1000),('天使',1000); -- 转账 SET autocommit = 0; START TRANSACTION; UPDATE account SET balance = 500 WHERE username = '麦克雷'; UPDATE account SET balance = 1500 WHERE username = '天使'; COMMIT; SELECT * FROM account;
事务的隔离级别
/* 当同事运行多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致并发问题 对于2个事务 T1 T2 脏读:T1读取了T2更新但还没提交的字段,若T2回滚,T1读取的内容就是临时无效的; 不可重复读:T1读取一个字段,然后T2更新了该字段后,T1再读同一字段,值发生了改变; 幻读:T1从表中读取了一些字段,T2插入了一些新行之后,如果T1再次读取,就会多出几行。 设置隔离级别: read uncommited read commited repeatable read serializable mysql支持:四种, 默认隔离级别:repeatable read oracle支持:read commited,serializable,read only 默认隔离级别:read commited */
小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
-- 显示隔离级别 SELECT @@tx_isolation -- 设置隔离级别 SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED -- 设置保存点 savepoing 只能搭配rollback SET autocommit = 0; START TRANSACTION; DELETE FROM account WHERE id = 1; SAVEPOINT a; DELETE FROM account WHERE id = 2; ROLLBACK TO a;