Hibernate(十九): 异常"Session was already closed"
中,针对"Session was already closed"异常,我们发现最终调用了transactionContext.managedClose方法来关掉了session, 那么这个过程具体是什么样的? 这篇中将加以梳理
.
在JDBCTransaction类(Transaction接口的一个实现类)具体决定是否要关session的方法closeIfRequired
里, 有这么一个复合条件决断: if(callback &&
transactionContext.shouldAutoClose() &&
!transactionContext.isClosed() ). 这三个条件分别代表什么?
首先看这个
callback, 在
JDBCTransaction
类的begin方法里(session.beginTransaction()方法最终要调用这个begin),看到这样的赋值: callback
= jdbcContext.registerCallbackIfNecessary();
registerCallbackIfNecessary方法的实现有些奇怪, 如下所示:
public boolean registerCallbackIfNecessary() {
if ( isTransactionCallbackRegistered ) {
return false;
}
else {
isTransactionCallbackRegistered = true;
return true;
}
}
如果isTransactionCallbackRegistered
为true就返回false, 如果是false,把它set为true后返回true. 有些奇怪. 不过, 这里不过多讨论了, debug时发现这里返回的是true.
再看第二个
transactionContext.shouldAutoClose().这里的主角transactionContext
是TransactionFactory.Context接口, 它什么时候set到
JDBCTransaction
类的,
JDBCTransaction类的构造方法里,即JDBCTransaction(JDBCContext jdbcContext, TransactionFactory.Context transactionContext). 为了追
transactionContext是从哪来的,看
这个构造方法又是何时调用. JDBCTransactionFactory里的createTransaction方法, 这个方法又在JDBCContext类的createTransaction( this, owner )
里,这里的的owner就是我们一直追的transactionContext,
那么这个owner是什么它又来自何方呢? 来自JDBCContext(Context owner, Connection
connection, Interceptor interceptor)构造方法.如下是整个跟踪路径:
最终在SessionImpl类的构造方法里对jdbcContext的赋值语句看到了,owner就是this,即SessionImpl对象.
this.jdbcContext = new JDBCContext( this, connection, interceptor );
也就是说SessionImpl类实现了TransactionFactory.Context接口(以实现JDBCContext.Context子接口方式间接来的).
看到这里, 根源找到了, 也就是说transactionContext.shouldAutoClose()是要调用
SessionImpl类的shouldAutoClose方法,
shouldAutoClose方法
又
有调用isAutoCloseSessionEnabled() &&
!isClosed(),最终看到是看isAutoCloseSessionEnabled方法里的autoCloseSessionEnabled属
性. 那这么个属性又是何时set的,源头在哪?
可从下图的方法调用栈,看到了源头: ThreadLocalSessionContext类里的isAutoCloseEnabled方法,
通过"return true;"写死的!
这
里有一个不舒服的地方: SessionImpl实现了JDBCContext.Context接口,
虽说接口JDBCContext.Context继承自TransactionFactory.Context,但让SessionImpl这么早地就跟
具体JDBCXXXX绑定还是有些别扭, 有些畸形.
对第二个条件的跟踪很是艰辛, 下面看第三个条件: !transactionContext.isClosed(), 应该说有了上面很是艰辛的分析后, 这里很自然地得知这里的第三个条件是调用了
SessionImpl
实现类的相应方法. (这里有个注意点:
isClosed方法恰好也是SessionImplementor接口定义的,这样在SessionImpl(父类)里一石二鸟地对两个接口定义的方法
做了实现,
再往一想,是不是可以抽出一个接口closable,让SessionImplementor和TransactionFactory.Context两
个接口做下继承?)
分享到:
相关推荐
安装安装pre-commit : pip install pre-commit 您应该能够编辑.pre-commit-config.yaml文件,以包括来自此存储库的配置: - repo : https://github.com/gvanderest/pylama-pre-commit rev : 0.1.2 hooks : - id : ...
修改commit信息 git log oneline -n,查看n条log信息 git rebase -i HEAD~n,n条commit进行rebase 将需要修改的commit信息,将pick命令改为 r 命令;ESC 输入 :wq 回车 开始修改commit信息,修改完,ESC 输入 :wq ...
当对话使用for update子串打开一个游标时, 所有返回集中的数据行都将处于行级(Row-X)独占式锁定, 其他对象只能查询这些数据行,不能进行update、delete或select...for update操作。 insert / update / ...
lucky-commit:自定义您的git commit哈希!
NULL 博文链接:https://tianjun309.iteye.com/blog/854393
pre-commit-docker:https:pre-commit.com打包为CI的Docker映像
在使用 Git 命令(例如 rebase、cherry-pick 等)时,存储您需要的[Commit ID]是一个有用的 CLI。 :rocket: 如何使用 :fire: 安装$ npm install -g commit-pocket :person_juggling: 入门$ commit-pocket :backpack...
commit-comments 会根据你代码中评论的变化而自动创建一个提交评论的无序列表。使用关键字 @commit 写评论时,commit-comments 会你在点击提交时,自动添加你的评论信息。依赖:GNU sed 需要在 post-commit 中移除 @...
将您的 git commit 兴奋变为现实! 转: $ git commit -m " adding file :) " $ git commit -m " adding another file :D :O :p " 进入这些 git commit 消息: 添加文件 :grinning_face_with_smiling_eyes: ...
提交消息编辑器 以方便的方式编辑提交消息。 特征 从最近的提交中选择一个较早的提交消息 编辑表单中的提交消息 ...commit-message-editor.view.defaultView :编辑器的默认视图(文本区域或表单) commit-message-e
--limit=[(int)limit]:默认情况下它只显示/导出最后一次提交。 使用此参数来定位更多提交。 --start=[(int)start]:提交的起始偏移量。 --format=[array|json|md|console]:导出的格式。 默认情况下,导出显示到...
18. session.getTransaction().commit(); 19. }catch(Exception e) { 20. e.printStackTrace(); 21. session.getTransaction().rollback(); 22. }finally { 23. HibernateUtils.closeSession(session); 24. } ...
git-emoji-guide::pencil2:git commit表情符号指南Git提交注释使用表情指北
提交前GoLang 一组用于Golang的git pre-commit挂钩,支持模块。 需要挂钩管理框架。安装您可以将以下代码段复制/粘贴到.pre-commit-config.yaml文件中。 注意可以在找到更加充实的版本 # ==========================...
持久化类的对象,在hibernate应用中可以处于三种状态(根据对象和session之间的关系进行划分): 1. 临时态,瞬态:特点: a) 在数据库中没有记录和它对应 b) 和session没有任何关系 c) New 出来的对象,都处于临时...
今天小编就为大家分享一篇关于PDO::commit讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
用法:将本bat文件(不可改名)存在svn服务器端安装目录\仓库名\hooks下(该目录下有多个*.tmpl文件,包括pre-commit.tmpl即linux下的提交钩子,而pre-commit.bat为windows下的提交钩子),并修改文件中相应目录(共...
完整的git commit > changelog > release工作流程和约定。 现在仅适用于Node.js项目。 感谢的灵感。 安装 npm install -D @picgo/bump-version # or yarn add -D @picgo/bump-version 另外,在package.json的顶层...
gitmoji-cli:gitmoji互动客户端在commit信息时使用gitmojis