一、数据并发带来的各种情况
①脏读:事务A读到事务B尚未提交的数据,并基于这个数据进行后续操作
②不可重复读:事务A读取数据后,被事务B修改或删除,事务A再次读取时前后两次读取的数据不一致
③幻像读:事务A读取数据后,事务B新增了数据,事务A再次读取是前后两次读取的数据不一致
不可重复读和幻想读的区别:
幻象读和不可重复读是两个容易混淆的概念,前者是指读到了其它已经提交事务的新增数据,而后者是指读到了已经提交事务的更改数据(更改或删除),为了避免这两种情况,采取的对策是不同的,防止读取到更改数据,只需要对操作的数据添加行级锁,阻止操作中的数据发生变化,而防止读取到新增数据,则往往需要添加表级锁——将整个表锁定,防止新增数据(Oracle使用多版本数据的方式实现)。
④第一类更新丢失:事务A和事务B同时访问同一个数据,事务B先提交修改,事务A回滚操作。导致事务B的修改丢失
⑤第二类更新丢失:事务A和事务B同时访问同一个数据,事务B先提交修改,事务A再提交。导致事务B的修改被覆盖
第一类更新丢失是很严重的操作,如果控制不当,可能导致在一个长时间的大型事务中,所有的操作都被回滚。所以所有的数据库都不支持这种并发情况。
二、数据库的锁机制
从锁的作用范围来分,可以分为:行级锁和表级锁
从锁的排他性来分,可以分为:共享锁和独占锁(排他锁),其中共享锁允许共享,但阻止独占锁。独占锁不但不允许共享锁,且不允许其它独占锁
于是组合起来就有:
①行共享锁:允许多个会话共享锁定的行数据,但不允许对这些行的独占锁。例如select ...for update
②行独占锁:对行进行独占,不允许其它的共享锁(表,行)、独占锁(表,行)和表共享行独占锁。例如insert,update
③表共享锁:允许多个会话共享表数据,但不允许其它的独占锁(表,行)、表共享行独占锁。可以实现表级事务一致性
④表独占锁:对表进行独占,不允许其它的共享锁(表,行)、读占锁(表,行)和表共享行独占锁。达到序列化操作级别
⑤表共享行独占锁:允许多个会话共享表数据,但同一时刻只能有一个行独占锁。可以达到数据共享同时防止脏读、不可重复读、幻像读
表共享锁定可以让会话具有对表事务级一致性访问,因为其它会话在你提交或者回溯该事务并释放对该表的锁定之前不能更改这个被锁定的表(因为要修改表的记录,就必须获得行独占锁,但是共享锁会阻止独占锁的获取,这样原来其它正在读取表记录的事务就不会出现脏读、不可重复读、幻像读的情况了);
表共享行独占锁与其不同则是多了一个行独占,这样效率更高。
三、事务隔离级别
尽管数据库为用户提供了锁的DML操作方式,但直接使用锁管理是非常麻烦的,因此数据库为用户提供了自动锁机制。只要用户指定会话的事务隔离级别,数据库就会分析事务中的SQL语句,然后自动为事务操作的数据资源添加上适合的锁。此外数据库还会维护这些锁,当一个资源上的锁数目太多时,自动进行锁升级以提高系统的运行性能,而这一过程对用户来说完全是透明的
下面是ANSI ISO92定义的4个事务隔离级别以及对应的对数据并发的处理
READ COMMITITED:不允许读取未提交的数据,但可以读取已提交的数据。所以可能出现不可重复读、和幻像读(读的过程依然可以被修改、增加、删除)
REPEATABLE READ:通过行锁定,在读的数据不允许其它进程修改。确保已读取的数据不被修改、删除(不可重复读)但无法阻止其它进程写入新数据,所以不能确保读取到新的数据(幻像读)
SERIALIZABLE:通过表锁定,彻底禁止读取期间其它进程的修改、删除(屏蔽不可重复读)和增加(屏蔽幻像读)
但是不管是那种隔离级别,对第一类丢失更新都是不能接收的
解决方案:为了避免上面出现的几种情况,在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同。
● 未授权读取,也称为读未提交(Read Uncommitted):允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。
● 授权读取,也称为读提交(Read Committed):允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
● 可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但是有时可能出现幻影数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
● 序列化(Serializable):提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
分享到:
相关推荐
3. 事务管理:确保事务的ACID属性,使用合适的事务隔离级别防止并发问题。 4. 日志监控:启用日志跟踪,便于调试和性能分析。 总之,Hibernate 5.4.17.Final作为官方发布的稳定版本,具备了强大的ORM功能和性能...
本章节我们将深入探讨Hibernate 5在数据持久化和事务管理方面的特性与用法。 **1. 数据持久化** 数据持久化是通过Hibernate的核心接口Session来实现的。Session提供了对数据库的 CRUD(创建、读取、更新、删除)...
在具体实践中,开发者应根据业务场景选择合适的事务隔离级别和并发控制策略。例如,对于读多写少的场景,乐观锁和较高的事务隔离级别(如Repeatable Read)可能是更好的选择。而对于写操作频繁的情况,悲观锁和更低...
在 Hibernate 中,事务隔离级别是指数据库系统提供的一种机制,以解决并发事务带来的问题。为了确保数据库的可靠性和一致性,Hibernate 提供了四种事务隔离级别,分别是 Serializable、Repeatable Read、Read ...
这包括但不限于数据类型的映射、特殊函数的支持、事务隔离级别的设置以及DML语句(如INSERT、UPDATE、DELETE)的生成。 使用瀚高数据库Hibernate方言,开发者可以轻松地将现有的Hibernate项目迁移到瀚高数据库,...
在更新数据时,Hibernate会检查版本号或时间戳,如果发现有其他事务在此期间也修改了数据,就会抛出并发异常,从而避免数据冲突。 总结来说,Hibernate的事务管理和并发控制是保证数据一致性和完整性的关键机制。...
- 使用合适的事务隔离级别,平衡并发性和数据一致性。 8. **其他策略**: - 使用预编译语句(PreparedStatement)代替字符串拼接的 SQL,防止 SQL 注入并提高执行效率。 - 分析 SQL 执行计划,定位慢查询并优化...
事务隔离级别决定了事务如何与其他事务交互以及如何处理数据的一致性和可重复性问题。常见的隔离级别有: - **读未提交(Read Uncommitted)**:最低隔离级别,允许读取未提交数据,可能导致脏读。 - **读已提交(Read...
10. **事务隔离级别与并发控制** Hibernate遵循JTA(Java Transaction API)规范处理事务,源码中的TransactionHelper类实现了不同隔离级别的事务控制。同时,乐观锁和悲观锁机制也是并发控制的关键,如Version和...
- **隔离性**(Isolation):并发事务之间相互隔离,避免数据冲突。 - **持久性**(Durability):一旦事务提交,其结果是永久性的。 2. **并发问题** 当多个用户或事务同时访问数据库时,可能出现以下并发问题...
Hibernate提供了四种事务隔离级别:读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)和串行化(SERIALIZABLE)。开发者可以根据应用场景选择合适的隔离级别。此外,...
9. **实体状态与生命周期**:理解Hibernate中的临时态、持久态、瞬时态和脱管态对于正确处理并发事务至关重要。 10. **最佳实践**:包括合理设计实体关系、避免N+1查询、使用批处理等,都是提升并发性能的关键。 ...
隔离性防止了多个并发事务间的相互干扰。持久性意味着一旦事务提交,其结果将是永久性的,即使系统故障也不会丢失。 #### 1.3 一级缓存的工作原理 一级缓存主要负责存储实体对象,当对象被加载到Session时,它们会...
在 Hibernate 中,可以通过设置 hibernate.connection.isolation 属性来指定事务隔离级别。 例如: ```xml <property name="hibernate.connection.isolation">2 ``` 这将设置事务隔离级别为 READ_COMMITTED。 解决...
在本篇“Spring Hibernate 事务管理学习笔记(二)”中,我们将深入探讨Spring框架与Hibernate集成时如何实现高效、安全的事务管理。这是一篇关于源码分析和技术工具使用的文章,适合对Java开发和数据库操作有基础...
Hibernate还允许开发者通过配置设置不同的事务隔离级别,以满足不同应用场景下的需求。常见的隔离级别包括: - `READ_UNCOMMITTED` - `READ_COMMITTED` - `REPEATABLE_READ` - `SERIALIZABLE` 这些级别的选择取决...
同时,还要注意合理配置事务隔离级别,如读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)和串行化(SERIALIZABLE),以平衡数据一致性与性能。 总之,深入学习和掌握...
2. 事务隔离级别:Hibernate的版本管理机制与数据库的事务隔离级别相结合,可以实现不同级别的并发控制。例如,在可重复读(Repeatable Read)隔离级别下,虽然能防止脏读,但可能会出现幻读,此时版本管理机制可以...
在Hibernate的配置文件中,可以设置事务相关的属性,比如默认的事务隔离级别、是否自动开始事务等。例如: ```xml <property name="hibernate.connection.isolation">2</property> <!-- 2对应READ_COMMITTED隔离...
3. **隔离级别:**包括READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ和SERIALIZABLE,它们定义了并发事务之间的可见性。例如,`SERIALIZABLE`是最高的隔离级别,防止脏读、不可重复读和幻读,但性能较低。 4....