休眠自动提交命令强制MySQL在过多的磁盘I / O中运行
親愛的大家,
我敢肯定,你們中的許多人都在使用Hibernate和MySQL,我自己在這里和那里都使用它。 通常,編程模型是不錯(cuò)的,但是普通的JDBC可以快很多已經(jīng)不是什么秘密了。 在這篇文章中,我想引起您的注意Hibernate在您的MySQL服務(wù)器中引起的一個(gè)小問題。
如果跟蹤Hibernate發(fā)送到MySQL數(shù)據(jù)庫的SQL,就會(huì)發(fā)現(xiàn)一致地,Hibernate以“ SET autocommit = 0”開始每個(gè)事務(wù),并以“ commit”結(jié)束,然后是“ SET autocommit = 1”。 這些語句看似無害,但它們使MySQL將某些內(nèi)部狀態(tài)刷新到磁盤上。 簡而言之,每次Hibernate調(diào)用這兩個(gè)語句之一時(shí),MySQL都會(huì)編寫通常不會(huì)編寫的內(nèi)容。 因此,與使用普通JDBC相比,使用Hibernate會(huì)使MySQL服務(wù)器在磁盤上的依賴更多。
我做了一個(gè)小實(shí)驗(yàn)來證明這一點(diǎn)。 要重復(fù)此實(shí)驗(yàn),請找到帶有MySQL數(shù)據(jù)庫的空閑計(jì)算機(jī)。 機(jī)器不應(yīng)運(yùn)行任何會(huì)導(dǎo)致磁盤I / O的東西,否則效果將不像我看到的那么容易。
首先,我發(fā)送了一整串“ SELECT DUAL DUAL;” 命令進(jìn)入MySQL提示。 像這樣:
while true; doecho "SELECT 1 FROM DUAL;" done | mysql查看iostat(8)的輸出,結(jié)果表明機(jī)器上沒有I / O。 top(1)確實(shí)表明機(jī)器正在運(yùn)行。 由此可見,這些SELECT語句不會(huì)引起磁盤I / O。
接下來,我添加了Hibernate的自動(dòng)提交命令,如下所示。
while true; doecho "SET AUTOCOMMIT=0;"echo "SELECT 1 FROM DUAL;"echo "COMMIT;"echo "SET AUTOCOMMIT=1;" done | mysql這次,iostat(8)確實(shí)表明存在磁盤I / O。 MySQL服務(wù)器比以前更努力地工作,同時(shí)仍然提供完全相同的答案。 這僅來自單個(gè)線程。 您的應(yīng)用程序可能會(huì)在多個(gè)線程和連接上同時(shí)發(fā)出這些語句,從而加劇了問題。
對于無論如何都會(huì)導(dǎo)致I / O的查詢,我認(rèn)為這種開銷可以忽略不計(jì)。 對于小型讀取查詢,這意味著您突然在數(shù)據(jù)庫服務(wù)器上執(zhí)行磁盤I / O。
我還沒有找到一種方法來向Hibernate解釋我不想讓它將自動(dòng)提交語句發(fā)送到數(shù)據(jù)庫。 您可以在Hibernate中關(guān)閉自動(dòng)提交功能,但是只能關(guān)閉Hibernate的內(nèi)部自動(dòng)提交功能。 它不會(huì)停止將這些命令發(fā)送到數(shù)據(jù)庫。
讀取Hibernate源代碼(尤其是org.hibernate.transaction.JDBCTransaction的源代碼)可以看到,休眠使它在每次事務(wù)之前強(qiáng)制自動(dòng)提交連接失敗,并在之后重置它。 這是硬編碼的。 休眠*想要*自動(dòng)提交為關(guān)閉。
如果我的MySQL服務(wù)器僅服務(wù)于啟用了Hibernate的應(yīng)用程序,我可能會(huì)考慮將數(shù)據(jù)庫服務(wù)器的默認(rèn)自動(dòng)提交模式關(guān)閉。 另外,我可以使用elideSetAutoCommits標(biāo)志,這可能會(huì)減少自動(dòng)提交切換的數(shù)量。 但是,這嚴(yán)重破壞了POLA 。 另外,我的服務(wù)器不僅僅提供支持Hibernate的應(yīng)用程序,因此更改默認(rèn)設(shè)置肯定會(huì)破壞其他地方。
所以,這讓我陷入困境。 我不能告訴Hibernate不要發(fā)出“ SET autocommit”,JDBC驅(qū)動(dòng)程序不會(huì)禁止它們,也不能告訴MySQL忽略它們。
參考: Hibernate發(fā)送自動(dòng)提交命令會(huì)強(qiáng)制MySQL在Java Monitor論壇上從我們的JCG合作伙伴 Kees Jan 做過多的磁盤I / O。
快樂編碼 拜倫相關(guān)文章:
- Hibernate映射集合性能問題
- DataNucleus 3.0與Hibernate 3.5
- 提升您的休眠引擎
- GWT 2 Spring 3 JPA 2 Hibernate 3.5教程
- JBoss 4.2.x Spring 3 JPA Hibernate教程
翻譯自: https://www.javacodegeeks.com/2011/07/hibernate-autocommit-commands-force.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的休眠自动提交命令强制MySQL在过多的磁盘I / O中运行的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 专为内容创作者设计 联想集团推出Thin
- 下一篇: 克苏鲁风格恐怖游戏《Holstin》St