hibernate 和 mybatis 的 session 都不是线程安全的,为什么还要用?

106 天前
 iintothewind
很多集合操作本来可以很方便的 paralStream 然后调用数据库处理,
或者从 servlet 主线程拿到数据提交异步操作处理。

但由于 hibernate 和 mybatis 的 session 都不是线程安全的,
导致在多线程环境下,
通过 hibernate 和 mybatis 的数据库改动可能会出现问题,

如果从多线程操作数据库的角度考虑,
我是真的不喜欢这俩老掉牙的难用的框架,
真的不喜欢。

大家有什么看法?
4591 次点击
所在节点    Java
61 条回复
NeroKamin
106 天前
你想要的是一个能够自动维护管理各线程 session 的东西,而不应该是一个线程安全的 session ,否则就是你对 session 的理解有误
iintothewind
106 天前
@NeroKamin #41 其实框架设计的时候就不设计 session, 直接处理就好了, jpa 标准并不重要.
NeroKamin
106 天前
@iintothewind #42 怎么可能不设计 session ,session 是和数据库交互所必需的。而且有这个东西也不意味着你必须得用这个啊,你可以用 SessionFactory 来管理 session 而避免直接使用 Session ,或者不满足你的需求你可以自己再进行封装。
iintothewind
106 天前
@NeroKamin #43 .net 的 linq 如何? 有 session 吗?
iPisces77
106 天前
parallelStream()我就用来导入数据,没有任何问题呀
interim
106 天前
@Vegetable 这就是地图炮的含金量?
lucasdev
106 天前
我说说个人理解哈:
1. 在 parallelStream 之前,Java 又不是没有多线程,Session 不是线程安全与它老不老掉牙没什么关系吧
2. Session 是用来管理数据库连接和事务的,肯定不能多线程共享,但在每个线程中 openSession 是不是可以满足楼主需求?
3. LINQ providers ,例如 LINQ To SQL 的 DataContext 、Entity Framework 的 DbContext ,和 Session 是类似的概念,它们也不是线程安全的
NeroKamin
106 天前
@iintothewind #44 linq 只是处理数据的抽象层而已,为什么拿来和 hibernate 和 mybatis 对比?
ZGame
106 天前
@iintothewind c#的 Linq 不是指查询数据库,Linq to Sql 通过 DataContext 去和数据库连接 ,他应该也不是线程安全的。。
wantstark
106 天前
这个问题问的、真无趣
ByteFlow
106 天前
使用 `SqlSessionFactoryBuilder` 默认创建的是 `DefaultSqlSessionFactory`。应该是可以使用另一个实现类 [`SqlSessionManager`]( https://github.com/mybatis/mybatis-3/blob/master/src/main/java/org/apache/ibatis/session/SqlSessionManager.java) 这个类代替的,这个类每次都会获取当前线程绑定的 `SqlSession`,应该是可以完成你说的任务的。这个类网上资料比较少,可以试一下。
summerLast
106 天前
您说的有道理,问题是哪些部分是可并行的哪些部分是需要串行的,还有两者如何更好的结合对这个问题会更有帮助,

针对不可并行的任务并性化操作时,框架如果能直接设置当前是否多线程调用,然后进行锁的操作或抛出异常对开发者心智要求也会降低,门槛也会降低,如果框架没有该功能就需要开发者针对自己的场景进行处理,这一切也没那么难,但如果有会更好一些

回到问题为什么还要用 没有更好的替代。
hzgit
106 天前
我感觉 LZ 可能搞错问题的方向了,推荐了解下连接池,看看是不是能解决你的问题
summerLast
106 天前
根据目前的硬件架构 多线程操作同一资源,锁是必须存在,锁的开启和关闭是有开销代价的,因此锁不在数据库层就在 应用层,而锁要不要用显然应用层会更好区分这个问题,至于是放在框架还是放在业务代码,这个就仁者见仁智者见智了,redis 就没这个心智负担
Chinsung
106 天前
你确定是这俩玩意的问题?
作用域:
单例( Singleton ):在整个应用程序中只创建一个 bean 实例,默认为单例。
原型( Prototype ):每次请求时都会创建一个新的 bean 实例。
会话( Session ):在 Web 应用程序中,每个会话都会创建一个 bean 实例。
请求( Request ):在 Web 应用程序中,每个请求都会创建一个 bean 实例。

你可以试试每次都创新一个新的 hibernate 或者 mybatis 实例来使用,看看到底是哪层的问题

按照你的描述来说,如果是 hibernate 或者 mybatis 不支持多线程使用,不应该是 sql 执行结果不对,而是经常生成的 sql 错误,不是吗?
Plutooo
106 天前
难道不是多线程操作数据库本身就破坏了隔离性?
cs419
106 天前
众口难调,流行的框架都是面向大众需求的
这种少见的用法 也不是不支持
看了下 mybatis 框架 给你留口子了

接口 SqlSessionFactory 与默认实现 DefaultSqlSessionFactory
SqlSession 与 DefaultSqlSession
自己包一下 就成了
你再发布到仓库 大伙都能用上

就好比 自动填充创建时间、更新时间、多租户等等
mybatis 官方没这些功能
mybatis plus 可以

今天这些框架不支持
明天有没有 session plus 取决于你的执行力
iintothewind
106 天前
@Chinsung 这个跟 spring 没关系的。
iintothewind
106 天前
@cs419
@ZGame 其实在多线程上线文里,session 跟 connection 是一回事,linq 及其类似组件都是依赖 connection 构建的, 本身后续的都是一系列流式的操作, 而这些操作既没有暴露 connection 也没有改变 connection 的状态, 所以才是线程安全的。 所以才说, 数据访问层的设计其实不需要有 session ,也可以做的很好用。
chaoschick
105 天前
太年轻了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1065374

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX