多条语句作为一个整体进行操作的功能,一系列操作必须全部执行,而不能仅执行一部分;要么全部成功,要么全部失败
例如,一个转账操作:
– 从id=1的账户给id=2的账户转账100元
– 第一步:将id=1的A账户余额减去100
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
– 第二步:将id=2的B账户余额加上100
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
这两条SQL语句必须全部执行,或者,由于某些原因,如果第一条语句成功,第二条语句失败,就必须全部撤销。
数据库事务具有ACID这4个特性:
持久性是通过 redo log (重做日志)来保证的;
原子性是通过 undo log(回滚日志) 来保证的;
隔离性是通过 MVCC(多版本并发控制) 或锁机制来保证的;
一致性则是通过持久性+原子性+隔离性来保证;
待学习补充?
手动把多条sql语句作为一个事务执行;
BEGIN开启一个事务,使用COMMIT提交事务,commit将事务内的所有sql所做的修改永久保存,如果commit语句执行失败了,整个事务也会失败,例如:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
主动让事务失败,可以使用ROLLBACK回滚事务,整个事务就会失败,例如:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
ROLLBACK;
问题1:为什么事务需要隔离?
当数据库上有多个事务同时执行的时候,就可能出现脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)的问题,为了解决这些问题,就有了“隔离级别”的概念
问题2:什么是脏读、不可重复读、幻读?
问题3:不可重复读和幻读有什么区别?
了解完事务可能出现的问题,再看事务的隔离级别
数据库事务的隔离级别有4个,由低到高依次为读未提交(Read uncommitted) 、读已提交(Read committed) 、可重复读(Repeatable read) 、串行化(Serializable) ,这四个级别可以逐个解决脏读 、不可重复读 、幻读 这几类问题
隔离的越严实,效率就会越低;
几种隔离机制可能出现的问题:
Q5: 可重复读为什么会出现幻读的现象?
Q5 :MySQL的InnoDB引擎默认隔离级别是可重复读;但是它很大程度上避免幻读现象;
Q4:每种隔离机制的使用场景有哪些?
可重复读: