什么是事务?
事务,是工作中的基本逻辑单元。一个事务可能包括数据库的一系列操作,而一个完整的事务保证这些操作都被正确地同步到数据库中,不会发生数据不完整或者错误,或者受到其他干扰。
事务的4个特性
原子性:即作为一个事务,它是不可分割的整体,只有全部操作都完成了,才算结束;其中任何一个操作执行失败,整个事务都要撤销。
一致性:即事务不能破坏数据库的完整性和业务逻辑的一致性。事务不管成功还是失败,事务结束时,整个数据库内部数据都是正确的。
隔离性:即在并发的数据库操作时,不同的事务操作相同的数据时,每个事务都有自己的完整的数据空间。一个事务不会看到或拿到另一个事务正修改到一半的数据,这些数据要么是另一个事务修改前的,要么是另一个事务修改后提交的。这个特性,是为了在数据库并发操作过程中,保证所有并发操作的正确性。
持久性:即事务成功提交后,数据就被永久地保存进数据库,重新启动数据库系统后,数据仍然保存在数据库系统中。
Hibernate支持的3种事务工厂
JDBCTransactionFactory:产生数据库JDBC的事务。通过JDBC的API来开始和结束事务,适用于任何Java环境,这是Hibernate的默认值。
JTATransactionFactory:产生托管环境下的事务。如果在上下文环境中存在运行的事务,则由容器管理,否则,启动一个新事务并使用bean管理。通过JTA来开始和事务结束,适用于JavaEE托管环境。
CMTTransactionFactory:产生托管环境下的事务。委托容器管理JTA事务。在Java应用程序中不必编写开始和结束事务的程序代码。
并发控制
更新丢失(Lost Update)
两个事务都更新同一行数据,如果一个事务执行失败,导致事务回滚,会把另一个事务的更新结果也丢失
脏读(Dirty read)
如果第二个事务读取了第一个事务修改的但是还没有提交的数据,结果第一个事务最后发生回滚,数据更新没有被保存到数据库中,那么第二个事务读到的数据就是不正确的,是被第一个事务弄脏的数据,所以这种现象叫脏读。
不可重复读(Unrepeatable read)
两个事务都读取同一行数据,一个事务修改数据并提交,另一个事务也修改数据并提交
幻读(Phantom read)
一个事务执行两次查询,结果发现第二次查询的结果比第一次查询的结果数据多了,这可能是因为另一个事务在两次查询之间插入了新行,这就是所谓的“幻读”问题。
数据库隔离级别
1.读未提交级别(read uncommitted isolation)
如果设置为这个级别,当某个事务新插入了数据,或者更新修改了数据,但是这个事务还没有提交。那么另一个事务能看到这些新插入或者修改的但未提交的数据。如果第一个事务结果是提交失败,这样第二个事务select语句的结果就会发生脏读。所以设置为读未提交级别不能避免脏读问题。
2.读已提交级别(read committed isolation)
如果设置为这个级别,那么一个事务只能读取被提交了的数据。所以如果一个数据在被另一个事务更改而事务未被提交,那么其他是看不到的。这能够避免脏读问题。但是,如果一个事务执行了两次同一个查询,但是在两次查询期间,其他事务更新或删除了数据,那么两个查询结果会不一样,可能出现不可重复读问题。
3.可重复读级别(repeatable read isolation)
如果设置为这个级别,那么一个事务对数据执行读取或写入操作时,锁定了这些数据行,其他事务不能对数据执行删除或者更新操作。所以它可以避免读已提交级别无法避免的不可重复读问题。但是,其他事务仍然可能插入新的数据,所以有可能发生幻读问题。
4.串行化事务(serializable)
执行多个串行事务和一个一个串行地执行,他们的结果一样,它使用完全与其他事务隔离的事务。比如:如果一个事务已经在操作某行数据了,那么另一个事务如果也想操作这行,那么不管它的操作会不会与第一个事务的操作发生冲突,它都必须停下来,等待第一个事务结束,这个事务才能恢复运行。
隔离级别的配置
在Hibernate的配置文件中,可以设置Hibernate.connection.isolation属性来设置全局的隔离级别。
乐观锁(optimistic locking)
乐观锁并没有对任何操作加锁,它只是在事务更新记录时,对事务进行检查,看自从上次读取这条记录后,它是否被其他事务修改。如果被修改了,那么这个事务就会回滚。检查的开销比完成隔离的开销低多了,而且它只有在发现修改冲突时才会发生回滚的开销。
1.使用version实现乐观锁
(在数据库中,使用version字段来跟踪记录的修改。每次修改记录,记录的version都会递增,那么事务在更新记录时,会先检查记录此时的版本号是否与这个事务上次读取记录的版本号一致,如果不一样,说明数据已经被别的事务修改了)
注意:
使用version需要在数据库中增加一个整数类型的version列,相应的对应的实体对象模型中需要增加version属性;version元素必须跟在id元素的后面
使用version设置乐观锁需要在class元素下使用version元素
<version name="?" column="?">
2.使用时间戳实现乐观锁
(每次修改记录时,都会记录下这个修改操作的时间戳。那么事务在跟新记录时,先检查记录此时的时间戳是否与这个事务上读取记录的时间戳一致,如果不一致,说明数据已经被别的事务修改了)
注意:
使用timestamp设置乐观锁需要在class元素下使用timestamp元素,在数据库增加一个timestamp类型的相应字段,在对应的实体对象模型中需要增加相应字段;timestamp元素必须跟在id元素后面
<timestamp name="?" column="?">
3.对比字段值实现乐观锁
(此方法不推荐使用)
<class name="" dynamic-update="true" optimistic-lock="dirty" table="">
dynamic-update="true":Hibernate产生的sql update语句只更新变化字段。
optimistic-lock="dirty":where子句只包含被更新过的属性.
optimistic-lock="all":where子句包含对象的所有属性.
悲观锁
悲观锁是在更新数据时把记录锁住,防止其他事务读写这个记录。所以无论事务间操作是否有冲突,使用悲观锁都会有额外的开销
注意:
使用悲观锁的事务会锁住记录,其他访问这个记录的事务会被一直阻塞,直到这个使用锁的事务提交或者释放了锁。但是,悲观锁不阻止增加新记录,所以执行同样的查询,可能返回不同数量的结果
悲观锁的多个锁机制
LockMode.FORCE:类似于LockMode.UPGRADE,只是对于带版本号的实体,它迫使实体的版本递增。
LockMode.NONE:不加锁,这是默认的锁定模式。但是,如果检索的数据不是从缓存中得到,而是需要从数据库中读取时,会自动地采用READ共享锁模式。
LockMode.READ:当Hibernate被设置为可重复读级别或者可串行化级别时,Hibernate将自动使用这种锁模式来读取数据。
LockMode.WRITE:当向数据库中插入或者更新数据时,Hibernate会自动使用这种锁。这种锁机制只是作为内部使用,不能作为load()和lock()的参数。
LockMode.UPGRADE:使用悲观锁。默认情况下,数据库使用共享锁来执行查询操作。使用了悲观锁后,Hibernate检索数据时使用的SQL语句如下: select * from Tabel where .... for update for update子句代表为检索操作加上锁,这个时候,其他事务,无论读操作还是写操作,都无法访问相关的数据
LockMode.UPGRADE_NOWAIT:类似于LockMode.UPGRADE,在Oracle中select for update nowait子句中,nowait说明了执行该select语句时,如果不能立刻获得悲观锁,那么不会等待其他事务释放锁,而是抛出一个异常。
分享到:
相关推荐
【标题】:Hibernate事务与并发问题处理 【描述】:本文深入探讨了在使用Hibernate框架时,如何管理和解决事务及并发问题。主要关注点在于事务的ACID特性以及并发操作可能导致的数据不一致性。 【标签】:技术 ...
Hibernate事务与并发问题处理[收集].pdf
本文将深入探讨Hibernate中的事务和并发控制,这对于开发高效、稳定的数据库应用至关重要。 首先,我们来理解Hibernate中的事务管理。在数据库操作中,事务是保证数据一致性的重要手段。一个事务包含了一组数据库...
Hibernate 对事务并发处理 在 Hibernate 中,对事务并发处理是非常重要的, especialmente 在多用户环境中。事务处理的目的是为了保证数据的可靠性和一致性。 事务四个特性 ACID 1. 原子性(Atomicity):事务...
Hibernate作为一个ORM框架,它对JDBC进行了封装,提供了更高级别的对象和API来处理事务。在Hibernate中,事务可以通过配置为JDBC事务或JTA事务。默认情况下,如果没有明确配置,Hibernate会使用JDBC事务。配置JDBC...
一、Hibernate事务管理 在数据库操作中,事务确保了数据的一致性和完整性。Hibernate提供了四种事务隔离级别:读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)和串行化...
### 详解Hibernate事务处理机制 #### 一、引言 Hibernate作为一款优秀的对象关系映射(ORM)框架,在Java开发领域扮演着极其重要的角色。它不仅简化了数据持久化的复杂性,还提供了一系列强大的功能来支持高效的...
3. **Hibernate事务配置:**在Spring中,需要配置Hibernate SessionFactory,并将其注入到需要进行数据库操作的服务中。同时,通过`PlatformTransactionManager`接口(如HibernateTransactionManager)配置事务管理...
本教程主要聚焦于Hibernate中的事务并发处理,包括悲观锁和乐观锁两种策略,这对于我们理解如何在高并发环境中确保数据的一致性和完整性至关重要。 首先,事务是数据库操作的基本单元,它确保一组操作要么全部成功...
#### 三、事务并发处理 Hibernate 提供了两种主要的并发控制机制: 1. **乐观锁(Optimistic Locking)**:假设数据不会经常冲突,只有在提交时才会进行冲突检测。Hibernate 通过版本字段实现自动乐观并发控制。 2....
### Hibernate事务管理 #### 非托管环境下的事务处理 在非托管环境中,如独立的Java应用程序或Web应用中,Hibernate通过其内部的连接池机制管理数据库连接。为了执行事务操作,开发者需要遵循以下步骤: 1. **...
**Hibernate事务管理详解** 在Java开发中,尤其是在企业级应用中,事务管理是不可或缺的一部分。Hibernate作为一款流行的ORM(对象关系映射)框架,提供了强大的事务处理能力。本篇文章将深入探讨Hibernate中的事务...
Hibernate作为一款流行的ORM框架,它简化了与数据库的交互,但同时也需要开发者理解其背后的事务处理机制。 首先,Hibernate支持两种类型的事务管理:JDBC连接管理和JTA(Java Transaction API)资源管理。它并未...
【hibernate事务管理机制】是指在使用Hibernate框架进行数据库操作时,如何管理和协调事务的一系列规则和策略。事务管理是确保数据一致性、完整性和并发控制的重要机制。 **悲观锁**是预防性的锁定策略,它假设并发...
《课程hibernate的事务和并发》主要探讨了在Hibernate框架中如何管理和处理事务以及并发控制。Hibernate作为一款流行的Java ORM(对象关系映射)工具,其事务处理和并发控制策略对于开发高效、稳定的数据库应用至关...
9. **实体状态与生命周期**:理解Hibernate中的临时态、持久态、瞬时态和脱管态对于正确处理并发事务至关重要。 10. **最佳实践**:包括合理设计实体关系、避免N+1查询、使用批处理等,都是提升并发性能的关键。 ...
在Java的持久化框架Hibernate中,版本管理机制是实现事务并发控制的重要手段。它通过维护对象的版本信息,确保在多线程环境下数据的一致性和完整性。本文将深入探讨Hibernate中的版本管理机制及其在控制事务并发中的...
### Hibernate事务处理详解 #### 一、事务处理概念与特性 事务处理是数据库操作中一个核心的概念,尤其在处理复杂的业务逻辑时,确保数据的一致性和完整性至关重要。Hibernate作为Java领域中广泛使用的对象关系...
**一、Hibernate事务的概念** 事务是一组数据库操作,这些操作被视为一个逻辑单元,要么全部执行,要么全部不执行。这是为了保证数据的一致性。在Hibernate中,事务管理通常通过SessionFactory和Session接口来实现。...