要想看看攔截器使用方法的具體范例,可以看看 org.apache.tomcat.jdbc.pool.interceptor.ConnectionState。這個(gè)簡(jiǎn)單的攔截器緩存了三個(gè)屬性:autoCommit、readOnly、transactionIsolation,為的是避免系統(tǒng)與數(shù)據(jù)庫(kù)之間無(wú)用的往返。
當(dāng)需求增加時(shí),姜維連接池核心增加更多的攔截器。歡迎貢獻(xiàn)你的才智!
攔截器當(dāng)然并不局限于 java.sql.Connection,當(dāng)然也可以對(duì)方法調(diào)用的任何結(jié)果進(jìn)行包裝。你可以構(gòu)建查詢性能分析器,以便當(dāng)查詢運(yùn)行時(shí)間超過(guò)預(yù)期時(shí)間時(shí)提供 JMX 通知。
JDBC 攔截器是通過(guò) jdbcInterceptor 屬性來(lái)配置的。該屬性值包含一列由分號(hào)分隔的類名。如果這些類名非完全限定,就會(huì)在它們的前面加上 org.apache.tomcat.jdbc.pool.interceptor. 前綴。
范例:
jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState; org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
它實(shí)際上等同于:
jdbcInterceptors="ConnectionState;StatementFinalizer"
攔截器也同樣有屬性。攔截器的屬性指定在類名后的括號(hào)里,如果設(shè)置多個(gè)屬性,則用逗號(hào)分隔開(kāi)。
范例:
jdbcInterceptors="ConnectionState;StatementFinalizer(useEquals=true)"
系統(tǒng)會(huì)自動(dòng)忽略屬性名稱、屬性值以及類名前后多余的空格字符。
所有攔截器的抽象基類,無(wú)法實(shí)例化。
屬性 |
描述 |
useEquals |
(布爾值)如果希望 ProxyConnection 類使用 String.equals,則設(shè)為 true;當(dāng)希望在對(duì)比方法名時(shí)使用 ==,則設(shè)為 false。默認(rèn)為 true。 |
它能為下列屬性緩存連接:autoCommit、readOnly、transactionIsolation 及 catalog。這是一種性能增強(qiáng)功能,當(dāng)利用已設(shè)定的值來(lái)調(diào)用 getter 與 setter 時(shí),它能夠避免往返數(shù)據(jù)庫(kù)。
跟蹤所有使用 createStatement、prepareStatement 或 prepareCall 的語(yǔ)句,當(dāng)連接返回池后,關(guān)閉這些語(yǔ)句。
屬性 |
描述 |
trace |
(以字符串形式表示的布爾值)對(duì)未關(guān)閉語(yǔ)句進(jìn)行跟蹤。當(dāng)啟用跟蹤且連接被關(guān)閉時(shí),如果相關(guān)語(yǔ)句沒(méi)有關(guān)閉,則攔截器會(huì)記錄所有的堆棧跟蹤。默認(rèn)值為 false。 |
緩存連接中的 PreparedStatement 或 CallableStatement 實(shí)例。
它會(huì)針對(duì)每個(gè)連接對(duì)這些語(yǔ)句進(jìn)行緩存,然后計(jì)算池中所有連接的整體緩存數(shù),如果緩存數(shù)超過(guò)了限制 max,就不再對(duì)隨后的語(yǔ)句進(jìn)行緩存,而是直接關(guān)閉它們。
屬性 |
描述 |
prepared |
(以字符串形式表示的布爾值)對(duì)使用 prepareStatement 調(diào)用創(chuàng)建的 PreparedStatement 實(shí)例進(jìn)行緩存。默認(rèn)為 true |
callable |
(以字符串形式表示的布爾值)對(duì)使用 prepareCall 調(diào)用創(chuàng)建的 CallableStatement 實(shí)例進(jìn)行緩存。默認(rèn)為 false |
max |
(以字符串形式表示的整型值)連接池中的緩存語(yǔ)句的數(shù)量限制。默認(rèn)為 50 |
請(qǐng)參看 48392。攔截器會(huì)包裝語(yǔ)句和結(jié)果集,從而防止對(duì)使用了 ResultSet.getStatement().getConnection() 和 Statement.getConnection() 方法的實(shí)際連接進(jìn)行訪問(wèn)。
當(dāng)新語(yǔ)句創(chuàng)建時(shí),自動(dòng)調(diào)用 java.sql.Statement.setQueryTimeout(seconds)。池本身并不會(huì)讓查詢超時(shí),完全是依靠 JDBC 驅(qū)動(dòng)來(lái)強(qiáng)制查詢超時(shí)。
屬性 |
描述 |
queryTimeout |
(以字符串形式表示的整型值)查詢超時(shí)的毫秒數(shù)。默認(rèn)為 1000 毫秒。 |
當(dāng)查詢超過(guò)失敗容差值時(shí),記錄查詢性能并發(fā)布日志項(xiàng)目。使用的日志級(jí)別為 WARN。
屬性 |
描述 |
threshold |
(以字符串形式表示的整型值)查詢應(yīng)超時(shí)多少毫秒才發(fā)布日志警告。默認(rèn)為 1000 毫秒 |
maxQueries |
(以字符串形式表示的整型值)為保留內(nèi)存空間,所能記錄的最大查詢數(shù)量。默認(rèn)為 1000 |
logSlow |
(以字符串形式表示的布爾值)如果想記錄較慢的查詢,設(shè)為 true。默認(rèn)為 true |
logFailed |
(以字符串形式表示的布爾值)如果想記錄失敗查詢,設(shè)為 true。默認(rèn)為 true |
這是對(duì) SlowQueryReport 的擴(kuò)展,除了發(fā)布日志項(xiàng)目外,它還發(fā)布 JMX 通知,以便監(jiān)視工具作出相關(guān)反應(yīng)。該類從其父類繼承了所有屬性。它使用了 Tomcat 的 JMX 引擎,所以在 Tomcat 容器外部是無(wú)效的。使用該類時(shí),默認(rèn)情況下,是通過(guò) ConnectionPool MBean 來(lái)發(fā)送 JMX 通知。如果 notifyPool=false,則 SlowQueryReportJmx 也可以注冊(cè)一個(gè) MBean。
屬性 |
描述 |
notifyPool |
(以字符串形式表示的布爾值)如果希望用 SlowQueryReportJmx MBean 發(fā)送 JMX 通知,則設(shè)為 false。默認(rèn)為 true |
objectName |
字符串。定義一個(gè)有效的 javax.management.ObjectName 字符串,用于將這一對(duì)象注冊(cè)到平臺(tái)所用的 mbean 服務(wù)器上。默認(rèn)值為 null。可以使用 tomcat.jdbc:type=org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReportJmx,name=the-name-of-the-pool 來(lái)注冊(cè)對(duì)象。 |
當(dāng)連接簽出池中后,廢棄計(jì)時(shí)器即開(kāi)始計(jì)時(shí)。這意味著如果超時(shí)為 30 秒,而你使用連接運(yùn)行了 10 個(gè) 10秒的查詢,那么它就會(huì)被標(biāo)為廢棄,并可能依靠 abandonWhenPercentageFull 屬性重新聲明。每次成功地在連接上執(zhí)行操作或執(zhí)行查詢時(shí),該攔截器就會(huì)重設(shè)簽出計(jì)時(shí)器。