java - Should a single thread only acquire a single connection from a connection pool?
问题描述
I am using ORMLite (Java) with HikariCP and I have a lot of code that's called asynchronously i.e. CompletableFuture.supplyAsync(Supplier). Inside a Supplier I have various calls to different ORMLite Dao objects inside these tasks. I ran into a deadlock scenario and found that increasing the size of the connection pool seemed to have fixed the issue.
After some research, I found that this is a well-documented problem. Having looked at the information provided here:
"Each thread is waiting for a second database connection, and none would become available since all threads are blocked."
This caught my eye. When looking at the ORMLite source code, I found that for each Dao method called, a connection is acquired. In my case, I am calling multiple Dao methods in each asynchronous task I create via CompletableFuture
which brings me to my question.
My understanding is that I should only acquire a single connection in each thread so is there a way to do this with ORMLite? Bearing in mind I have calls to different Dao objects and having done some further research, Dao#callBatchTasks(Callable)
caught my eye but I am unsure whether I can have calls to different Dao objects inside the Callable. Or is there a flaw in my logic or something fundamental I am missing in my write-up?
解决方案
我发现每调用一个 Dao 方法,都会获取一个连接
如果ORMLite需要去数据库,它需要得到一个连接,对吧?有什么地方做得不对吗?
我的理解是我应该只在每个线程中获取一个连接,那么有没有办法用 ORMLite 做到这一点?
我不认为有什么说一个线程不能打开多个数据库连接。只要在您完成te操作时它们都关闭,那么我认为这很好。如果您正在查询都存在于同一个数据库上的不同 DAO,那么只要您完成了连接,您实际上就可以每次都重用该连接。即,如果您使用打开的连接对结果进行分页,然后在中间查询另一个表,那么这可能会搞砸游标。但是,如果您先执行 a dao1.queryAll()
,然后执行 a ,则dao2.queryAll()
可以使用相同的连接,因为第一个查询已经完成。
但是如果您使用的是连接池,该池应该在 ORMLite 的 ConnectionSource 的帮助下为您进行连接管理。如果需要,该池应该为您创建一个新连接,否则会重用旧连接。对数据库连接进行限制有点奇怪。
Dao#callBatchTasks(Callable)
引起了我的注意,但我不确定是否可以调用 Callable 中的不同 Dao 对象。
你可以调用不同的 dao 对象,只要它们都在同一个数据库上。您实际上可以调用一个连接到不同数据库的 dao,但您无法保证数据库之间的事务。
例如,如果您执行以下操作。
- 你打电话
dao1.callBatchTasks(callable)
- 在您的
Callable
中,您调用dao2.delete(entity1)
which 有效。 - 仍然在
Callable
, 你调用dao2.delete(entity2)
which throws。 - 事务
dao1
将被回滚,但entity1
仍将被删除。
推荐阅读
- sql - 正确的嵌套查询
- javascript - 通过根据位置比较对数组进行切片,随机抓取三个位置
- python - 在对熊猫数据框进行分组操作期间,为无法聚合的列保留数据的最佳方法是什么?
- javascript - 从 html 表单获取用户输入并将其写入文本、csv 或其他数据库文件(express.js、node.js、html)
- linux - 将更多文件的行数与文件名结合起来
- flutter - 处置后使用了 TextEditingController
- python - Python BeautifulSoup,如何更改下拉列表并获取 html?
- django - 将现有博客文章导入 django-cms-blog
- xcode - 如何在另一个视图控制器中更改标签文本
- javascript - 在 HTML 页面上显示对象的动态数量