Java程式中insert 執行慢的原因,以及c3p0連線池的配置
今天遇到一個問題,程式中一個insert 操作特別慢, 一直從來沒有遇到過,select 操作如果資料量大的話,是有可能出現這種情況的,但是單條insert插入操作出現這種情況,不知道從何查原因了,debug了確定了就是insert這個操作慢,一開始分析是不是mysql原因,在Navicat上insert操作,嗖嗖的,排除,然後想到是不是資料庫這張表一直在操作,檢視下還真不是,然後想到是不是資料庫連線慢,但是用到資料庫連線池,程式已啟動就已經連上了啊,看了連線池配置,我靠,maxPoolSize=1,誰設定的,最大連線數為1,這個不是主要的,如果正常情況下也沒有這麼糟糕,況且使用者沒有那麼多操作,看了非使用者操作,有一個定時任務,一直在資料庫操作,一直佔用這個唯一的連線。終於發現問題,我maxPoolSize 改為10後,測試沒有發現問題,但是還沒完,經過一段時間的執行,怎麼感覺有insert慢的問題,而且是越來越慢,之前的那個定時任務是10分鐘一次,經過測試,這個定時任務一次執行完全超過了10分鐘,而且,quartz 定時任務是多執行緒的,一次沒有執行完,到第二次執行不會結束本次執行,會多一個執行緒繼續執行,難關會隨著時間越來越慢,這個定時任務是有多長啊,隨著時間推移,形成了越來越多的執行緒,但是總會達到臨界點的,這樣得情況,就需要調大定時任務時間間隔,太頻繁也沒有卵用。不知道後續還會不會有其他問題。
我們用的是c3p0連線池,配置:
<!--acquireIncrement:連結用完了自動增量3個。 -->
<property name="acquireIncrement">3</property>
<!--acquireRetryAttempts:連結失敗後重新試30次。-->
<property name="acquireRetryAttempts">30</property>
<!--acquireRetryDelay;兩次連線中間隔1000毫秒。 -->
<property name="acquireRetryDelay">1000</property>
<!--autoCommitOnClose:連線關閉時預設將所有未提交的操作回滾。 -->
<property name="autoCommitOnClose">false</property>
<!--automaticTestTable:c3p0測試表,沒什麼用。-->
<property name="automaticTestTable">Test</property>
<!--breakAfterAcquireFailure:出錯時不把正在提交的資料拋棄。-->
<property name="breakAfterAcquireFailure">false</property>
<!--checkoutTimeout:100毫秒後如果sql資料沒有執行完將會報錯,如果設定成0,那麼將會無限的等待。 -->
<property name="checkoutTimeout">100</property>
<!--connectionTesterClassName:通過實現ConnectionTester或QueryConnectionTester的類來測試連線。類名需制定全路徑。Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester-->
<property name="connectionTesterClassName"></property>
<!--factoryClassLocation:指定c3p0 libraries的路徑,如果(通常都是這樣)在本地即可獲得那麼無需設定,預設null即可。-->
<property name="factoryClassLocation">null</property>
<!--forceIgnoreUnresolvedTransactions:作者強烈建議不使用的一個屬性。-->
<property name="forceIgnoreUnresolvedTransactions">false</property>
<!--idleConnectionTestPeriod:每60秒檢查所有連線池中的空閒連線。-->
<property name="idleConnectionTestPeriod">60</property>
<!--initialPoolSize:初始化時獲取三個連線,取值應在minPoolSize與maxPoolSize之間。 -->
<property name="initialPoolSize">3</property>
<!--maxIdleTime:最大空閒時間,60秒內未使用則連線被丟棄。若為0則永不丟棄。-->
<property name="maxIdleTime">60</property>
<!--maxPoolSize:連線池中保留的最大連線數。 -->
<property name="maxPoolSize">15</property>
<!--maxStatements:最大連結數。-->
<property name="maxStatements">100</property>
<!--maxStatementsPerConnection:定義了連線池內單個連線所擁有的最大快取statements數。Default: 0 -->
<property name="maxStatementsPerConnection"></property>
<!--numHelperThreads:非同步操作,提升效能通過多執行緒實現多個操作同時被執行。Default: 3-->
<property name="numHelperThreads">3</property>
<!--overrideDefaultUser:當用戶呼叫getConnection()時使root使用者成為去獲取連線的使用者。主要用於連線池連線非c3p0的資料來源時。Default: null-->
<property name="overrideDefaultUser">root</property>
<!--overrideDefaultPassword:與overrideDefaultUser引數對應使用的一個引數。Default: null-->
<property name="overrideDefaultPassword">password</property>
<!--password:密碼。Default: null-->
<property name="password"></property>
<!--preferredTestQuery:定義所有連線測試都執行的測試語句。在使用連線測試的情況下這個一顯著提高測試速度。注意: 測試的表必須在初始資料來源的時候就存在。Default: null-->
<property name="preferredTestQuery">select id from test where id=1</property>
<!--propertyCycle:使用者修改系統配置引數執行前最多等待300秒。Default: 300 -->
<property name="propertyCycle">300</property>
<!--testConnectionOnCheckout:因效能消耗大請只在需要的時候使用它。Default: false -->
<property name="testConnectionOnCheckout">false</property>
<!--testConnectionOnCheckin:如果設為true那麼在取得連線的同時將校驗連線的有效性。Default: false -->
<property name="testConnectionOnCheckin">true</property>
<!--user:使用者名稱。Default: null-->
<property name="user">root</property>
<!--usesTraditionalReflectiveProxies:動態反射代理。Default: false-->
<property name="usesTraditionalReflectiveProxies">false</property>
這就能驗證我的問題了,如果最大連線數設定為1,那麼資料庫連線當下只能有一個連線,如果其他程式要連線資料庫,就只能加入到連線池佇列中,等待當前連線完成。