Hibernate 处理并发问题

本文探讨了在多个事务并发运行时可能出现的第一类丢失更新、脏读、虚读和不可重复读等问题,以及如何通过锁机制和事务隔离级别来解决这些问题。详细介绍了数据库的四种事务隔离级别,并给出了在MySQL中设置隔离级别的方法。在应用程序层面,可以通过Hibernate配置文件设定隔离级别,同时提出了悲观锁和乐观锁的实现策略,推荐在解决并发问题时优先考虑乐观锁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 多个事务并发运行时的并发问题

  • 第一类丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖;
  • 脏读:一个事务到另一个事务未提交的更新数据;
  • 虚度:一个事务到另一个事务已提交的新插入的数据;
  • 不可重复读:一个事务到另一事务已提交的更新的数据;
  • 第二类丢失更新:(不可重复读特例)提交一个事务时,覆盖另一个事务已提交的更新事务。

2 锁机制保证事务隔离性

对select用共享锁,insert、update或delete采用独占锁。

3 数据库的事务隔离级别

  • Serializable:串行化
  • Repeatable Read :可重复读
  • Read Commited:读已提交的数据(最常用)
  • Read Uncommited :读未提交的数据

各隔离级别所避免的并发问题如图3-1所示:

图3-1 各隔离级别所避免的并发问题

隔离级别越高,事务的并发性能就越低,图3-2展示了隔离级别与并发性能的关系:

图3-2  隔离级别与并发性能的关系

实际应用中通常采用Read Cmmitted的隔离级别。

3.1 mysql.exe中设置隔离级别

每个数据库连接都用一个全局变量@@tx_isolation表示事务的隔离级别。默认为Repeatable Read。设置隔离级别SQL命令如下:

如果要设置数据库系统 的全局隔离级别可用如下命令:

3.2 在应用程序中设置隔离级别

JDBC连接数据库使用的是数据库系统的默认隔离级别。

Hibernate的配置文件中可以显示的设置隔离级别:

  • 1:Read Uncommited
  • 2:Read Committed
  • 4:Repeated Read
  • 8:Serializable

4 在应用程序中使用锁机制解决并发问题

由上可知,当采用Read Committed隔离级别时,回导致不可重复读和第二类丢失更新的并发问题。采用悲观锁或乐观锁解决。(优先考虑乐观锁)

悲观锁的实现方式:

  • 方式一:在应用程序中显示指定采用数据库系统的独占锁来锁定数据资源。数据库默认使用共享锁来select记录。在Hibernate应用中ge加载t对象时可通过org.hibernate.LockMode指定锁定模式,对应的数据库SQL语句为select ... for update表示采用独占锁锁定查询记录
  • 方式二:在表中增加一个表明记录状态的LOCK字段。

乐观锁的实现方式:

  • 使用Hibernate的版本控制功能来实现(优先考虑)。在ORM映射中采用具有版本控制功能的<version>或<timestamp>元素控制。注意:这两个元素要紧跟在<id>元素后。
  • 将<class>元素的optimistic-lock属性设置为“all”,dynamic-update设置为true。(只适合在一个Session中对对象操作)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值