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

2024-08-16 07:39:26 +08:00
 iintothewind
很多集合操作本来可以很方便的 paralStream 然后调用数据库处理,
或者从 servlet 主线程拿到数据提交异步操作处理。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

© 2021 V2EX