对于Hibernate的openSession方法为什么不是线程安全的源码理解

Hibernate DialectResolutionInfo为null的根源与修复 DialectResolutionInfo是Hibernate启动过程中用于数据库方言推断的核心服务,其为null并非配置项缺失的表象问题,而是StandardServiceRegistry构建失败的深层信号。该服务依赖JdbcEnvironment初始化,而后者又强依赖DataSource和正确注入的hibernate.dialect等元数据。当ServiceRegistry未完成applySettings()与build()流程,或存在版本不兼容(如Spring Boot 3.x与Hibernate 5 阅读详情

首先,先明确几个概念。

1、局部变量不会受多线程影响。

2、成员变量会受到多线程影响。
多个线程调用的同一个对象的同一个方法:
如果方法里无成员变量,不受任何影响,
如果方法里有成员变量,只有读操作,不受影响,存在赋值操作,有影响。

第一点
SessionFactory和Session都是接口,SessionFactoryImpl和SessionImpl是其实现。

第二点
SessionFactoryImpl里的openSession方法如下,其中的 new SessionImpl(…)存在线程不安全的因素。

    @Override
        public Session openSession() {
            log.tracef( "Opening Hibernate Session.  tenant=%s, owner=%s", tenantIdentifier, sessionOwner );
            final SessionImpl session = new SessionImpl(
                    connection,
                    sessionFactory,
                    sessionOwner,
                    getTransactionCoordinator(),
                    autoJoinTransactions,
                    sessionFactory.settings.getRegionFactory().nextTimestamp(),
                    interceptor,
                    flushBeforeCompletion,
                    autoClose,
                    connectionReleaseMode,
                    tenantIdentifier
            );

            for ( SessionEventListener listener : listeners ) {
                session.getEventListenerManager().addListener( listener );
            }

            return session;
        }

第三点
通过观察下面SessionImpl的源码实现,可以发现在构造方法内部出现了对于成员变量的赋值的操作,所以线程不安全。

    SessionImpl(
            final Connection connection,
            final SessionFactoryImpl factory,
            final SessionOwner sessionOwner,
            final TransactionCoordinatorImpl transactionCoordinator,
            final boolean autoJoinTransactions,
            final long timestamp,
            final Interceptor interceptor,
            final boolean flushBeforeCompletionEnabled,
            final boolean autoCloseSessionEnabled,
            final ConnectionReleaseMode connectionReleaseMode,
            final String tenantIdentifier) {
        super( factory, tenantIdentifier );
        this.timestamp = timestamp;
        this.sessionOwner = sessionOwner;
        this.interceptor = interceptor == null ? EmptyInterceptor.INSTANCE : interceptor;
        this.actionQueue = new ActionQueue( this );
        this.persistenceContext = new StatefulPersistenceContext( this );

        this.autoCloseSessionEnabled = autoCloseSessionEnabled;
        this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;

        if ( transactionCoordinator == null ) {
            this.isTransactionCoordinatorShared = false;
            this.connectionReleaseMode = connectionReleaseMode;
            this.autoJoinTransactions = autoJoinTransactions;

            this.transactionCoordinator = new TransactionCoordinatorImpl( connection, this );
            this.transactionCoordinator.getJdbcCoordinator().getLogicalConnection().addObserver(
                    new ConnectionObserverStatsBridge( factory )
            );
        }
        else {
            if ( connection != null ) {
                throw new SessionException( "Cannot simultaneously share transaction context and specify connection" );
            }
            this.transactionCoordinator = transactionCoordinator;
            this.isTransactionCoordinatorShared = true;
            this.autoJoinTransactions = false;
            if ( autoJoinTransactions ) {
                LOG.debug(
                        "Session creation specified 'autoJoinTransactions', which is invalid in conjunction " +
                                "with sharing JDBC connection between sessions; ignoring"
                );
            }
            if ( connectionReleaseMode != transactionCoordinator.getJdbcCoordinator().getLogicalConnection().getConnectionReleaseMode() ) {
                LOG.debug(
                        "Session creation specified 'connectionReleaseMode', which is invalid in conjunction " +
                                "with sharing JDBC connection between sessions; ignoring"
                );
            }
            this.connectionReleaseMode = transactionCoordinator.getJdbcCoordinator().getLogicalConnection().getConnectionReleaseMode();

            // add a transaction observer so that we can handle delegating managed actions back to THIS session
            // versus the session that created (and therefore "owns") the transaction coordinator
            transactionObserver = new TransactionObserver() {
                @Override
                public void afterBegin(TransactionImplementor transaction) {
                }

                @Override
                public void beforeCompletion(TransactionImplementor transaction) {
                    if ( isOpen() && flushBeforeCompletionEnabled ) {
                        SessionImpl.this.managedFlush();
                    }
                    beforeTransactionCompletion( transaction );
                }

                @Override
                public void afterCompletion(boolean successful, TransactionImplementor transaction) {
                    afterTransactionCompletion( transaction, successful );
                    if ( isOpen() && autoCloseSessionEnabled ) {
                        managedClose();
                    }
                    transactionCoordinator.removeObserver( this );
                }
            };

            transactionCoordinator.addObserver( transactionObserver );
        }

        loadQueryInfluencers = new LoadQueryInfluencers( factory );

        if (factory.getStatistics().isStatisticsEnabled()) {
            factory.getStatisticsImplementor().openSession();
        }

      if ( TRACE_ENABLED )
           LOG.tracef( "Opened session at timestamp: %s", timestamp );
    }

当然,这些只是博主粗浅的理解。

Hibernate底层原理:从延迟加载到二级缓存的深度解析 Hibernate作为Java生态主流ORM框架,其本质是一套对象-关系映射决策系统,而非简单SQL生成器。理解其核心机制需回归JPA规范与数据库交互的基本原理:延迟加载是对象图导航的性能契约,依赖Session生命周期与代理机制;一级缓存是事务内状态快照管理,失效由flush、merge、refresh等操作主动驱动;二级缓存则需根据架构形态(单体/微服务/分布式)权衡一致性、性能与运维成本。这些机制共同决定了持久层的可靠性、可观察性与扩展边界。本文聚焦Hibernate 5.6+在真实生产环境中的行为逻 阅读详情

相关推荐

Hibernate SessionFactory().getCurrentSession()深度解析与实践

ORM(对象关系映射)技术是一种将数据库中的表映射到对象模型的技术。Hibernate ORM是一个开源的对象关系映射框架,它提供了从Java对象到关系数据库表的映射,以及反之亦然的数据存取和查询服务。Hibernate通过操作Java对象来实现与数据库的交互,大大简化了数据库编程工作。SessionFactory在Hibernate框架中扮演着非常关键的角色,它是线程安全的,并且是重量级的工厂类。其主要职责是构建和管理Session对象。

weixin_42360733的博客 426

转 hibernate中session的线程安全问题

[size=medium]Hibernate的基本特征是完成面向对象的程序设计语言到关系数据库的映射,在Hibernate中使用持久化对象PO(Persistent Object)完成持久化操作,对PO的操作必须在Session管理下才能同步到数据库, 但是这里的Session并非指HttpSession,可以理解为基于JDBC的Connnection,Session是 Hibernate运作的...

游云的专栏 290

Office如何通过VSTO进行WORD插件开发?

VSTO(Visual Studio Tools for Office )是VBA的替代,是一套用于创建自定义Office应用程序的Visual Studio工具包。VSTO可以用Visual Basic 或者Visual C#扩展Office应用程序(例如Word、Excel、PPT)。本文通过VSTO进行Word插件开发总结,并进行记录。

【cacrle】的博客 7322

hibernate中session的线程安全问题

Hibernate的基本特征是完成面向对象的程序设计语言到关系数据库的映射,在Hibernate中使用持久化对象PO(Persistent Object)完成持久化操作,对PO的操作必须在Session管理下才能同步到数据库, 但是这里的Session并非指HttpSession,可以理解为基于JDBC的Connnection,Session是 Hibernate运作的中心, 对象的生...

weixin_34304013的博客 183

统信UOS上Qt5.12.8离线安装保姆级教程(避坑网络登录与GCC选择)

本文提供统信UOS系统下Qt5.12.8离线安装的完整教程,涵盖环境准备、安装步骤、常见问题解决及开发优化建议。特别针对无网络环境下的登录验证跳过、GCC版本匹配等关键问题提供解决方案,帮助开发者快速搭建稳定的Qt开发环境。

weixin_30666401的博客 462

从零到一:TI AWR1843 Boost EVM与DCA1000 EVM的ADC数据采集实战指南

本文详细介绍了TI AWR1843 Boost EVM与DCA1000 EVM的ADC数据采集实战指南,涵盖硬件连接、软件配置、固件烧录、雷达参数设置及数据处理等关键步骤。通过MATLAB等工具,开发者可高效实现毫米波雷达数据采集,适用于自动驾驶、工业检测等领域。

weixin_29001327的博客 967

【hibernate源码解析】之Session

Session是Hibernate持久化操作的基础。Hibernate Session 之与Hibernate,相当于JDBC Connection相对于JDBC。那么Hibernate的Session从哪里来的呢。从代码中我们可以看出来 sessionFactory.openSession();Hibernate的Session是通过SessionFactory创建出来的。下面我们从代码中来看

爱生活,爱技术 1163

数字IC后端PR阶段Innovus,ICC,ICC2修复short万能脚本分享

数字IC后端PR阶段Innovus,ICC,ICC2修复short万能脚本分享

weixin_37584728的博客 3465

spring对session和事务的管理以及OpenSessionInViewFilter是如何工作的

  为了弄清楚spring对session和事务的管理以及OpenSessionInViewFilter是如何工作的,可监控以下类的日志: org.springframework.orm.hibernate3.support.OpenSessionInViewFilter,org.springframework.orm.hibernate3.HibernateTransactionManager,org.hibernate.transaction.JDBCTransaction,org.hibernate

Laurence的技术博客 1万+

autodl云服务器使用中的conda源报错

通过find path -name filename找到.condarc文件,在autodl服务器中,一般在/root/.condarc。为了利用jypyter打开conda虚拟环境运行,需要下载ipykenel。这个报错是源的问题,在通过源获取包元数据时出现了HTTP 429错误。通过conda换源解决。修改.condarc文件,命令: vim .condarc。但这样还不能解决问题,得把报错中有问题的源注释掉。通过以下命令添加清华镜像源。把报错的链接源注释如下。

Ty_kilig的博客 1584

redhawk:使用rh_setup.pl产生gsr模板

必须加的option工具会在rh_setup.pl给出提示,按照要求填写即可,另外工具会把所有填写的输入文件和信息放到rh_setup.init文件中,拷贝这个文件可在任何平级运行目录下,直接rh_setup.pl产生gsr以及run sta/dyn/em的脚本。rhsetup.pl -top top_cell_name -vdd_nets VDD 1.2 VDD2 1.2 -vss_nets VSS -frequency 100e6 (100m是默认值)更多学习内容请关注「拾陆楼」知识星球。

m0_61544122的博客 1055

Hibernate3.x openSession()与getCurrentSession()得到的连接的区别

测试1:openSession在不开启事务的情况下执行操作    Session session= SessionFactoryUtil.openSession();      (1):session.get(UserInfo.class,14L);  //执行成功,得到数据      (2):session.delete(new UserInfo(16L));  //执行成功

曾今拼命的想,现在却拼命的忘 737

详解vit_base_patch16_224

ViT-Base模型的核心思想是将输入图像划分为多个小块(patches),并使用Transformer架构来处理这些小块。具体来说,ViT-Base使用16x16像素的patch大小,输入图像的尺寸为224x224像素,这意味着每张图像将被划分为49个patch(22416×22416=14×14=19616224​×16224​=14×14=196个patch)。ViT-Base(ViT-B/16)通过将图像处理任务转化为序列处理任务。

具身机器人和通用AI 3233

hibernate学习---Configuration,Session,SessionFactory


 上一节我们讲到了Hibernate的测试,并且给出了测试代码,刚开始看见这个测试代码的同学估计是一头雾水把,所以这一节我们来讲一下测试代码。  本节主要内容: Configuration SessionFactory Session 首先我们再来看一下上一节的测试代码: //加载配置文件 Configuration config = n...

m0_37109682的博客 327

拆解全球18大“支付清算”体系:CLS、中国、美国、欧洲、日本、mBridge...

拆解全球18大“支付清算”体系:CLS、中国、美国、欧洲、日本、mBridge...

银行信息系统应用架构详解 887

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

SSH学习(十)Hibernate常用API详解及源码分析

学习Java的同学注意了!!!  学习过程中遇到什么问题或者想获取学习资源的话,欢迎扫描左栏的二维码加入微信公众号(codehzm)  我们一起学java! 新接触一个框架的目的就是想利用这个框架来为我们做一些工作,或者是让他来简化我们的工作,利用这个框架无非就是要利用这个框架所给我们提供的API去操作我们的数据,所以利用一个框架的好坏很大一部分取决于你对这个框架API的理

代码搬运工 1843

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Java程序员从笨鸟到菜鸟之(五十二)细谈Hibernate(三)Hibernate常用API详解及源码分析

Java程序员从笨鸟到菜鸟之(五十二)细谈Hibernate(三)Hibernate常用API详解及源码分析

uffvhj的博客 204

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Hibernate常用API详解及源码分析

新接触一个框架的目的就是想利用这个框架来为我们做一些工作,或者是让他来简化我们的工作,利用这个框架无非就是要利用这个框架所给我们提供的API去操作我们的数据,所以利用一个框架的好坏很大一部分取决于你对这个框架API的理解程度,所以在此篇博客中我们就一起来看一下Hibernate的API和配置文件的相信情况。下面我们一一来看一下: 一:使用SchemaExport自动创建数据库表 ...

weixin_30496751的博客 88

spring、hibernate源码分析二

从上篇文章分析得出,hibernate初始化时,flushBeforeCompletion、autoCloseSession默认为false releaseMode为auto。还有hibernate.jdbc.batch_size默认为0等。那现在来分析openSession和getCurrentSession的区别就不难了。     首先进入sessionFactory的实现类Session...

Zhou20072724的博客 282

Java程序员从笨鸟到菜鸟之(五十二)细谈Hibernate(三)Hibernate常用API详解及源码分析...

新接触一个框架的目的就是想利用这个框架来为我们做一些工作,或者是让他来简化我们的工作,利用这个框架无非就是要利用这个框架所给我们提供的API去操作我们的数据,所以利用一个框架的好坏很大一部分取决于你对这个框架API的理解程度,所以在此篇博客中我们就一起来看一下Hibernate的API和配置文件的相信情况。下面我们一一来看一下: 一:使用SchemaExport自动创建数据库表 我相...

122

【Hibernate】current_session_context_class的作用

sessionFactory.getCurrentSession()可以完成一系列的工作,当调用时,hibernate将session绑定到当前线程,事务结束后,hibernate将session从当前线程中释放,并且关闭session。当再次调用getCurrentSession()时,将得到一个新的session,并重新开始这一系列工作。 这样调用方法如下: Session session

lzm18064126848的专栏 1822

Java主流框架与源码:MyBatis / Hibernate

在深入源码之前,我们先从宏观上把握两者的定位差异。特性MyBatisHibernate定位半自动 ORM,SQL 由开发者控制全自动 ORM,SQL 由框架自动生成SQL 控制完全掌控,SQL 写在 XML 或注解中基于 HQL/Criteria,自动生成 SQL学习曲线较低,需熟悉 SQL较高,需理解 ORM 映射与缓存机制性能调优灵活,SQL 可精细优化依赖缓存与抓取策略,调优复杂缓存一级(SqlSession)与二级(Mapper)缓存。

mhmh123的博客 135

Java程序员从笨鸟到菜鸟之(五十二)细谈Hibernate(三)Hibernate常用API详解及源码分析--csdn 曹胜欢...

新接触一个框架的目的就是想利用这个框架来为我们做一些工作,或者是让他来简化我们的工作,利用这个框架无非就是要利用这个框架所给我们提供的API去操作我们的数据,所以利用一个框架的好坏很大一部分取决于你对这个框架API的理解程度,所以在此篇博客中我们就一起来看一下Hibernate的API和配置文件的相信情况。下面我们一一来看一下: 一:使用Schem...

weixin_33919941的博客 87
上一篇: mysql建立索引时中的length什么用
下一篇: 使用docker时出现wlan网络适配器驱动程序出现问题
github_32658299
博客等级 码龄11年 21粉丝 33原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值