Spring事务_事务的隔离级别_02
事务的隔离级别
尽管数据库为用户提供了锁的DML操作方式,但直接使用锁管理是十分麻烦的,因此数据库为用户提供了自动锁机制。
只要用户指定会话的事务隔离级别,数据库就会分析事务中的SQL语句,然后自动为事务操作的数据资源添加上合适的锁。此外数据库还会维护这些锁,当一个资源上的锁数据太多时,自动劲松锁升级以提高系统的运行性能,而这一过程对用户来说是完全透明的。
- ANSI/ISO SQL标准定义了4个等级的事务隔离级别,在相同的环境中,使用相同的输入,执行相同的工作,根据不同的隔离级别,可以导致不同的结果。不同的事务隔离级别能够解决的数据并发问题的能力是不同的。
隔离级别 | 脏读 | 不可重复读 | 幻象读 | 第一类丢失更新 | 第二类丢失更新 |
---|---|---|---|---|---|
read uncommitted | 允许 | 允许 | 允许 | 不允许 | 允许 |
read committed | 不允许 | 允许 | 允许 | 不允许 | 允许 |
repeatable read | 不允许 | 不允许 | 允许 | 不允许 | 不允许 |
serializable | 不允许 | 不允许 | 不允许 | 不允许 | 不允许 |
事务的隔离级别和数据库的并发性是对立的,两者此增彼长,一般来说使用Read uncommited隔离级别的数据库拥有最高的并发性和吞吐量,而使用Serializable事务隔离级别数据库的并发和吞吐量最低。
SQL 92定义Read uncommited主要提供非阻塞读的能力,Oracle虽然也支持Read uncommited级别的事务,但是它不支持脏读,所以Oracle的Read Committed就满足了SQL 92标准的repead read级别。
SQL 92推荐使用repeatable read来保证数据库的对一致性。
总结
-
数据库事务ACID
- 原子性 -要么成功,要么失败 - 一致性 -数据库的操作要和业务最终一致,A向B转账,不管成功或失败,账款总额不变 - 隔离性 -事务之间是独立的,相互不影响 - 持久性 -事务一旦提交,所有的数据必须持久化到数据库中
-
数据库事务并发问题
五中问题(3中数据访问问题2中更新问题) 1. 数据脏读 -A事务读取了B事务未提交的数据 2. 数据不可重复读 -A事务中两次读取不一致 3. 数据幻象读 -统计事务中,两次统计过程新增数据 4. 第一种更新丢失 -A事务撤销覆盖了B事务的提交数据 5. 第二种更新丢失 -A事务提交覆盖了B事务的更新数据
-
数据库使用锁机制解决数据并发问题
数据库锁机制解决数据并发问题 - 行级共享锁 -不阻止事务更新但是禁止表独占锁 - 行级独占锁 -防止其他事务获得共享锁定,共享独占锁定或者独占锁定 - 表共享锁定 - 防止其他事务表共享行独占锁或表独占锁定,允许在表中拥有多个行共享 - 和表共享锁定,该锁定可以让会话具有表事务级一致性访问。 - 表共享行独占 - 防止其他会话获得表共享、行独占、或者表独占锁定。允许其他行共享 - 定.只是一个表一次只能放置一个表共享行锁定。 - 表独占 - 防止其他任何会话锁定
-
由于数据库锁机制比较麻烦,数据库提供隔离事务级别自动分析SQL添加锁
事务级别 read uncommitted - 允许:脏读、不可重复读、幻象读、第二种更新丢失 - 不允许:第一种更新丢失 read committed - 允许:不可重复读,幻象读,第二种更新丢失 - 不允许:脏读,第一种更新丢失 repetable read - 允许:幻象读 - 不允许:脏读、不可重复读、第一种更新丢失、第二种更新丢失 serializable - 不允许:脏读、不可重复读、幻象读、第一种更新丢失、第二种更新丢失
不是所有的数据库都支持事务,即支持事务的数据库也并非支持所有的事务隔离级别,可以通过JDBC的Connection.getMetaData()方法获取DataBaseMetaDate对象,并通过该对象的supportTransctaions().supportsTransactionIsolationLevel(int level)方法查看地城数据库的支持情况。