事务: 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)
数据库常用的事务隔离级别都有哪些?都是什么原理?
读未提交(Read Uncommitted)
读提交(Read Committed)
可重复读(Repeated Read)
串行化(Serializable)
事务的隔离性
而事务的隔离性就是指,多个并发的事务同时访问一个数据库时,一个事务不应该被另一个事务所干扰,每个并发的事务间要相互进行隔离。
查看全局和session会话的事务隔离级别以及设置
SELECT @@global.tx_isolation,@@tx_isolation;
REPEATABLE-READ; REPEATABLE-READ
范例: SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
具体设置: set global transaction isolation level read committed; //全局的
具体设置: set session transaction isolation level read committed; //当前会话
事务隔离级别解释和原理
读未提交(Read Uncommitted)
可以读到未提交的内容。
在这种隔离级别下,查询是不会加锁的,也由于查询的不加锁,所以这种隔离级别的一致性是最差的,可能会产生“脏读”、“不可重复读”、“幻读”。
如无特殊情况,基本是不会使用这种隔离级别的。
读提交(Read Committed)
读提交: 就是只能读到已经提交了的内容。
这是各种系统中最常用的一种隔离级别,也是SQL Server和Oracle的默认隔离级别。
这种隔离级别能够有效的避免脏读,但除非在查询中显示的加锁,如:
select * from T where ID=2 lock in share mode;
select * from T where ID=2 for update;
不然,普通的查询是不会加锁的。
那为什么“读提交”同“读未提交”一样,都没有查询加锁,但是却能够避免脏读呢?
这就要说道另一个机制“快照(snapshot)”,而这种既能保证一致性又不加锁的读也被称为“快照读(Snapshot Read)”
优点: 快照读”可以完成高并发的查询,“读提交”只能避免“脏读”
缺点: 不能避免“不可重复读”和“幻读”。
可重复读(Repeated Read)
可重复读: 就是专门针对“不可重复读”这种情况而制定的隔离级别,可以有效的避免“不可重复读”。
它也是MySql的默认隔离级别。
在这个级别下,普通的查询同样是使用的“快照读”,
但是,和“读提交”不同的是,当事务启动时,就不允许进行“修改操作(Update)”了,
而“不可重复读”恰恰是因为两次读取之间进行了数据的修改。
优点:“可重复读”能够有效的避免“不可重复读”。
缺点: 避免不了“幻读”,因为幻读是由于“插入或者删除操作(Insert or Delete)”而产生的。
串行化(Serializable)
这是数据库最高的隔离级别,这种级别下,事务“串行化顺序执行”,也就是一个一个排队执行。
优点: 这种级别下,“脏读”、“不可重复读”、“幻读”都可以被避免。
缺点: 执行效率奇差,性能开销也最大,所以基本没人会用。
简单总结
为什么会出现“脏读”?因为没有“select”操作没有规矩。
为什么会出现“不可重复读”?因为“update”操作没有规矩。
为什么会出现“幻读”?因为“insert”和“delete”操作没有规矩。
“读未提(Read Uncommitted)”能预防啥?啥都预防不了。
“读提交(Read Committed)”能预防啥?使用“快照读(Snapshot Read)”,避免“脏读”,但是可能出现“不可重复读”和“幻读”。
“可重复读(Repeated Red)”能预防啥?使用“快照读(Snapshot Read)”,锁住被读取记录,避免出现“脏读”、“不可重复读”,但是可能出现“幻读”。
“串行化(Serializable)”能预防啥?排排坐,吃果果,有效避免“脏读”、“不可重复读”、“幻读”,不过效果谁用谁知道。
需要提交的事务
SQL语言分为五大类:
DDL(数据定义语言) - Create、Alter、Drop 这些语句自动提交,无需用Commit提交。
DQL(数据查询语言) - Select 查询语句不存在提交问题。
DML(数据操纵语言) - Insert、Update、Delete 这些语句需要Commit才能提交。
DTL(事务控制语言) - Commit、Rollback 事务提交与回滚语句。
DCL(数据控制语言) - Grant、Revoke 授予权限与回收权限语句。
所以,只有当执行插入(insert)、更新(update)、删除(delete)这些种类的语句时才需要提交(commit)