数据库事务的ACID和隔离级别
作者:Vic ,分类:Mysql 发布于 2021-10-23 01:04:08
什么是ACID?
- 事务操作数据不可分割的工作单元 , 一个事务中所有的操作 , 要么都执行 , 要么都不执行 , 这样能保证事务工作范围内的可控性 , 如果一个事务执行了一半就停止了 , 没有达到预期结果还导致了数据错乱 , 还需要进行数据补改还原措施 , 就失去了使用事务可控性意义 , 当然, 我们可以通过回滚来替代数据补改还原措施 .
- 事务从执行前到执行后需要保证预期结果的一致性 , 举个栗子: 事务内修改张三的名字为李四 , 事务提交后张三的名字必须是李四 , 能具备按照规则完成最基本的预设工作
- 数据库是一个多连接并发的服务 , 就有可能出现两个或多个连接对象的事务同时对同一条数据进行读写和修改, 就会导致交叉变更数据会和预期不一致 , 隔离级别可以解决该问题 , 下面我们会详解隔离级别.
- 事务处理完成后 , 对数据写和修改是永久的 , 数据库故障也不可对数据造成影响 , 保证了对数据的复用性和完整性
- 总结 : ACID的存在是解决事务内外容易产生意外场景的数据操作而制定技术性的规范和约束
数据库隔离级别
隔离界别
隔离级别 | 可避免 | 会发生的问题 | 描述 | 对应Java的设置Connection.setTransactionIsolation( Connection.隔离级别) |
Read-Uncommitted (读未提交) | - | 脏读 | - | TRANSACTION_READ_UNCOMMITTED |
Read-Committed (读已提交) | 脏读 | 不可重复读 | Oracle,SqlServer默认的级别 | TRANSACTION_READ_COMMITTED |
Repeatable-Read (可重复读) | 不可重复读 | 幻读 | mysql 默认的级别 | TRANSACTION_REPEATABLE_READ |
Serializable (串行化) | 幻读 | - | 最高的隔离级别,事务有序执行,前面的事务未提交,后面的事务等待 , 缺点是效率低 | TRANSACTION_SERIALIZABLE |
问题的场景
问题名称 | 产生的场景 | 解决方案 |
脏读 | 事务A读到事务B尚未提交的数据, 如果事务B回滚了, 就会产生脏读 | 设置隔离级别为提交读 |
不可重复读 | 事务内两次读取的数据内容不一致,一般是期间执行了update操作, 就会产生不可重复读 | 设置隔离级别为可重复读 |
幻读 | 事务内两次读取的数据的数量不一致, 一般是期间执行了insert 或delete操作,就会产生幻读 | 设置隔离级别为串行化读 |