首先数据库的特性就是 ACID;
Atomicity 原子性: 所有事务是一个整体, 要么全部成功, 要么失败
Consistency 一致性: 在事务开始和结束前, 要保持一致性状态
Isolation 隔离性: 对于同一个表的操作, 每个事务都是单独的, 不会影响其他事务.
Durability 持久性: 事务一旦提交, 数据库中的数据就是永久的了.
对于以上四种特性中的隔离性, 不同的策略会有不同的弊端: 脏读, 不可重复读, 幻读.
脏读: 就是一个事务读取了别的事务执行过程中未提交的数据.
不可重复读: 就是一个事务正在操作的数据被别的事务给修改了. 对于一下脏读是有区别的.
幻读: 就是一个事务刚更新了一批数据, 还未提交, 准备提交 时, 突然又插入了一条数据, 这就幻读.
具体对应什么策略呢: 未提交读, 已提交读, 可重复读, 可序列化
隔离级别 | 脏读可能性 | 不可重复读可能性 | 幻读可能性 | 加锁读 |
---|---|---|---|---|
READ UNCOMMITTED | 是 | 是 | 是 | 否 |
READ COMMITTED | 否 | 是 | 是 | 否 |
REPEATABLE READ | 否 | 否 | 是 | 否 |
SERIALIZABLE | 否 | 否 | 否 | 是 |
策略是什么意思呢?
未提交读: 就是两个事务 A 和 B, 在 A 中可以读到 B 中未提交 的数据, 这种隔离级别是最低的, 因为会有脏数据, 这种级别也只是在理论层面
提交读: 就是两个事务 A 和 B, 只有 A 事务提交了 B 才可以读到, 这种级别避免了脏数据, 但会存在不可重复读, Oracle 默认的隔离级别.
可重复读: 就是两个事务 A 和 B, 在 A 的事务中读取 B 中已提交的事务, A 事务中的数据是不变的. 但是在 A 提交时, 会对比最新的数据, 并更新. MySQL 的默认隔离级别.
可序列化: 还是两个事务, A 操作数据库时, B 只能等着. 相当于串行.
理解了上面的理论, 如何修改策略呢
1. 修改 MySQL 的配置文件 my.INI
- #
- - READ-UNCOMMITTED - READ-COMMITTED - REPEATABLE-READ - SERIALIZABLE
- [mysqld]
- transaction-isolation = REPEATABLE-READ
2. 通过命令
- SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
- SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
以上两个为会话级别, 下面是全局级别
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
spring 中的传播机制的理解:
一共七个, 一个个说也记不住 , 我们来假设情况:
两种情况 , 一种当前没有事务, 一种是当前有事务
spring 传播机制 | 当前没有事务 | 当前有事务 |
REQUIRED | 新建一个事务 | 加入这个事务中 |
SUPPORTS | 以非事务方式执行 | 加入 |
MANDATORY | 抛出异常 | 加入 |
REQUIRES_NEW | 新建 | 挂起就建 |
NOT_SUPPORTED | 以非事务运行 | 挂起,非事务运行 |
NEVER | 以非事务运行 | 抛出异常 |
NESTED | 执行 | 嵌套事务内执行 |
spring 中的隔离级别:
隔离级别 | 含义 |
ISOLATION_DEFAULT | 使用数据库默认的事务隔离级别 |
ISOLATION_READ_UNCOMMITTED | 允许读取尚未提交的修改,可能导致脏读、幻读和不可重复读 |
ISOLATION_READ_COMMITTED | 允许从已经提交的事务读取,可防止脏读、但幻读,不可重复读仍然有可能发生 |
ISOLATION_REPEATABLE_READ | 对相同字段的多次读取的结果是一致的,除非数据被当前事务自生修改。可防止脏读和不可重复读,但幻读仍有可能发生 |
ISOLATION_SERIALIZABLE | 完全服从 ACID 隔离原则,确保不发生脏读、不可重复读、和幻读,但执行效率最低。 |
来源: http://www.bubuko.com/infodetail-3104135.html