4种事务特性
- 原子性(Atomicity):事务包含的所有操作要么全部执行成功,要么全部失败回滚,强调的是事务的不可分割性;
- 一致性(Consistency): 事务执行前和执行后必须处于一次性状态,事务执行前后数据的完整性必须保持一致,例如:转账;
- 隔离性(isolation):一个事务执行过程中不应受到其他事务的影响,即多个并发事务之间要相互隔离
- 持久性(Durability):事务一旦结束,数据就持久到数据库
5种隔离级别
如果不考虑事务的隔离性会引发以下安全性问题:
- 脏读:一个事务读取到了另一个事务还未提交的数据;
- 不可重复读:一个事务读取到了另一个事务已经提交的update的数据导致多次查询结果不一致;【行锁】
- 幻读:一个事务读取到另一个事务已经提交的insert的数据导致多次查询结果不一致;【表锁】
解决读问题:设置隔离级别(4种)
# 查看当前全局事务隔离级别:
# MySQL5.6 及其更早的版本
select @@global.tx_isolation;
# MySQL5.7 及更高版本
select @@global.transaction_isolation;
# 修改 MySQL 全局默认事务隔离级别
# MySQL5.6 及其更早的版本
set global tx_isolation='read-uncommitted';
set global tx_isolation='read-committed';
set global tx_isolation='repeatable-read';
set global tx_isolation='serializable';
# MySQL5.7 及更高版本
set global transaction_isolation='read-uncommitted';
set global transaction_isolation='read-committed';
set global transaction_isolation='repeatable-read';
set global transaction_isolation='serializable';
- 未提交读(read uncommited): 所有事务都可以看到其他未提交事务的执行结果;此隔离级别很少在实际应用中使用,可能会发生脏读、不可重复读、幻读;【读不加锁;写瞬间加读锁,事务结束释放】
- *已提交读(read commited):事务只能看到已经提交事务所改变的数据,可能会发生不可重复读、幻读;【读瞬间加读锁,读完之后立即释放;写瞬间加写锁,事务结束才释放】
- *可重复读(repeatable read):mysql默认隔离级别,同一事务的多个实例在并发读取数据时,会看到同样的数据行,可能会发生幻读;(注: InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题)【读瞬间加读锁,事务完成之后才释放锁;写瞬间加写锁,事务结束才释放】
- 串行化(serializable):最高的隔离级别,它强制事务顺序,使之不可能相互冲突,可避免三种读,但可能导致大量的超时现象和锁竞争。【读瞬间加读锁;写瞬间加写锁】
只有串行化是表锁 ,其他都是行锁
注意:隔离性与并发性,此消彼长。
事务隔离级别不同实际是因为生产read view 的时间不同导致的
7种传播行为
- PROPAGATION_REQUIRED 支持当前事务,如果不存在 就新建一个 (默认)
- PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务
- PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常
保证没有在同一个事务中 - PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务
- PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务
- PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常
- PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行
在分布式系统中一般先执行不会对外界造成影响的操作(可以回滚的操作),后执行不可控,或者不能回滚的操作,不可回滚操作应当有且只有一个。
数据库量大的优化
原因:随着数据量的增多,sql语句效率下降。
解决方案:按照这个顺序优化;加索引,表分区(分流),分库分表、读写分离;
分区的优点:
- 不影响业务
- 放不同磁盘上
- 可以备份、回复,逐步进行;