如何查看mysql数据库连接池信息

如何查看mysql数据库连接池信息,第1张

1、把数据库驱动包 copy 到 %CATALINA_HOME%\common\lib 下。

2、修改 %CATALINA_HOME%\conf\server.xml 文件,在 <Host>节点下添加:

XML/HTML code?

<!-- appName 为项目名 --!>

<Context path="/appName" docBase="appName" auth="Container">

<Resource name="jdbc/MySQLDS" scope="Shareable"

type="javax.sql.DataSource"

url="jdbc:mysql://localhost:3306/test?useUnicode=true&charact-erEncoding=GBK"

driverClassName="com.mysql.jdbc.Driver"

username="root" password="111111"

maxWait="3000" maxIdle="100" maxActive="10" />

</Context>

(或者在 %appName%\META-INF 下建立 context.xml,内容为上面的代码。)

3、修改 web.xml,在 <web-app>节点下添加:

XML/HTML code?

import java.sql.Connection

import javax.naming.Context

import javax.naming.InitialContext

import javax.sql.DataSource

public class DBUtil {

public Connection getConnection() throws Exception {

Context context = new InitialContext()

// 获取数据源

DataSource ds = (DataSource) context.lookup("java:comp/env/jdbc/MySQLDS")

// 获取数据库连接

Connection conn = ds.getConnection()

if (conn != null &&!conn.isClosed()) {

return conn

} else {

return null

}

}

}

写JDBC connection pool 的注意事项有:

1. 有一个简单的函数从连接池中得到一个 Connection。

2. close 函数必须将connection 放回 数据库连接池。

3. 当数据库连接池中没有空闲的connection,数据库连接池必须能够自动增加connection 个数。

4. 当数据库连接池中的connection 个数在某一个特别的时间变得很大,但是以后很长时间只用其中一小部分,应该可以自动将多余的connection 关闭掉。

5. 如果可能,应该提供debug 信息报告没有关闭的new Connection 。

如果要new Connection 就可以直接从数据库连接池中返回Connection, 可以这样写( Mediator pattern ) (以下代码中使用了中文全角空格):

public class EasyConnection implements java.sql.Connection{

private Connection m_delegate = null

public EasyConnection(){

m_delegate = getConnectionFromPool()

}

 public void close(){

putConnectionBackToPool(m_delegate)

}

public PreparedStatement prepareStatement(String sql) throws SQLException{

m_delegate.prepareStatement(sql)

}

//...... other method

}

看来并不难。不过不建议这种写法,因为应该尽量避免使用Java Interface, 关于Java Interface 的缺点我另外再写文章讨论。大家关注的是Connection Pool 的实现方法。下面给出一种实现方法。

import java.sql.*

import java.lang.reflect.*

import java.util.*

import java.io.*

public class SimpleConnetionPool {

private static LinkedList m_notUsedConnection = new LinkedList()

private static HashSet m_usedUsedConnection = new HashSet()

private static String m_url = ""

private static String m_user = ""

private static String m_password = ""

static final boolean DEBUG = true

static private long m_lastClearClosedConnection = System.currentTimeMillis()

public static long CHECK_CLOSED_CONNECTION_TIME = 4 * 60 * 60 * 1000//4 hours

static {

initDriver()

}

private SimpleConnetionPool() {

}

private static void initDriver() {

Driver driver = null

//load mysql driver

try {

driver = (Driver) Class.forName("com.mysql.jdbc.Driver").newInstance()

installDriver(driver)

} catch (Exception e) {

}

//load postgresql driver

try {

driver = (Driver) Class.forName("org.postgresql.Driver").newInstance()

installDriver(driver)

} catch (Exception e) {

}

}

public static void installDriver(Driver driver) {

try {

DriverManager.registerDriver(driver)

} catch (Exception e) {

e.printStackTrace()

}

}

public static synchronized Connection getConnection() {

clearClosedConnection()

while (m_notUsedConnection.size() >0) {

try {

ConnectionWrapper wrapper = (ConnectionWrapper) m_notUsedConnection.removeFirst()

if (wrapper.connection.isClosed()) {

continue

}

m_usedUsedConnection.add(wrapper)

if (DEBUG) {

wrapper.debugInfo = new Throwable("Connection initial statement")

}

return wrapper.connection

} catch (Exception e) {

}

}

int newCount = getIncreasingConnectionCount()

LinkedList list = new LinkedList()

ConnectionWrapper wrapper = null

for (int i = 0i <newCounti++) {

wrapper = getNewConnection()

if (wrapper != null) {

list.add(wrapper)

}

}

if (list.size() == 0) {

return null

}

wrapper = (ConnectionWrapper) list.removeFirst()

m_usedUsedConnection.add(wrapper)

m_notUsedConnection.addAll(list)

list.clear()

return wrapper.connection

}

private static ConnectionWrapper getNewConnection() {

try {

Connection con = DriverManager.getConnection(m_url, m_user, m_password)

ConnectionWrapper wrapper = new ConnectionWrapper(con)

return wrapper

} catch (Exception e) {

e.printStackTrace()

}

return null

}

static synchronized void pushConnectionBackToPool(ConnectionWrapper con) {

boolean exist = m_usedUsedConnection.remove(con)

if (exist) {

m_notUsedConnection.addLast(con)

}

}

public static int close() {

int count = 0

Iterator iterator = m_notUsedConnection.iterator()

while (iterator.hasNext()) {

try {

( (ConnectionWrapper) iterator.next()).close()

count++

} catch (Exception e) {

}

}

m_notUsedConnection.clear()

iterator = m_usedUsedConnection.iterator()

while (iterator.hasNext()) {

try {

ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next()

wrapper.close()

if (DEBUG) {

wrapper.debugInfo.printStackTrace()

}

count++

} catch (Exception e) {

}

}

m_usedUsedConnection.clear()

return count

}

private static void clearClosedConnection() {

long time = System.currentTimeMillis()

//sometimes user change system time,just return

if (time <m_lastClearClosedConnection) {

time = m_lastClearClosedConnection

return

}

//no need check very often

if (time - m_lastClearClosedConnection <CHECK_CLOSED_CONNECTION_TIME) {

return

}

m_lastClearClosedConnection = time

//begin check

Iterator iterator = m_notUsedConnection.iterator()

while (iterator.hasNext()) {

ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next()

try {

if (wrapper.connection.isClosed()) {

iterator.remove()

}

} catch (Exception e) {

iterator.remove()

if (DEBUG) {

System.out.println("connection is closed, this connection initial StackTrace")

wrapper.debugInfo.printStackTrace()

}

}

}

//make connection pool size smaller if too big

int decrease = getDecreasingConnectionCount()

if (m_notUsedConnection.size() <decrease) {

return

}

while (decrease-- >0) {

ConnectionWrapper wrapper = (ConnectionWrapper) m_notUsedConnection.removeFirst()

try {

wrapper.connection.close()

} catch (Exception e) {

}

}

}

public static int getIncreasingConnectionCount() {

int count = 1

int current = getConnectionCount()

count = current / 4

if (count <1) {

count = 1

}

return count

}

public static int getDecreasingConnectionCount() {

int count = 0

int current = getConnectionCount()

if (current <10) {

return 0

}

return current / 3

}

public synchronized static void printDebugMsg() {

printDebugMsg(System.out)

}

public synchronized static void printDebugMsg(PrintStream out) {

if (DEBUG == false) {

return

}

StringBuffer msg = new StringBuffer()

msg.append("debug message in " + SimpleConnetionPool.class.getName())

msg.append("\r\n")

msg.append("total count is connection pool: " + getConnectionCount())

msg.append("\r\n")

msg.append("not used connection count: " + getNotUsedConnectionCount())

msg.append("\r\n")

msg.append("used connection, count: " + getUsedConnectionCount())

out.println(msg)

Iterator iterator = m_usedUsedConnection.iterator()

while (iterator.hasNext()) {

ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next()

wrapper.debugInfo.printStackTrace(out)

}

out.println()

}

public static synchronized int getNotUsedConnectionCount() {

return m_notUsedConnection.size()

}

public static synchronized int getUsedConnectionCount() {

return m_usedUsedConnection.size()

}

public static synchronized int getConnectionCount() {

return m_notUsedConnection.size() + m_usedUsedConnection.size()

}

public static String getUrl() {

return m_url

}

public static void setUrl(String url) {

if (url == null) {

return

}

m_url = url.trim()

}

public static String getUser() {

return m_user

}

public static void setUser(String user) {

if (user == null) {

return

}

m_user = user.trim()

}

public static String getPassword() {

return m_password

}

public static void setPassword(String password) {

if (password == null) {

return

}

m_password = password.trim()

}

}

class ConnectionWrapper implements InvocationHandler {

private final static String CLOSE_METHOD_NAME = "close"

public Connection connection = null

private Connection m_originConnection = null

public long lastAccessTime = System.currentTimeMillis()

Throwable debugInfo = new Throwable("Connection initial statement")

ConnectionWrapper(Connection con) {

this.connection = (Connection) Proxy.newProxyInstance(

con.getClass().getClassLoader(),

new Class[]{Connection.class}, this)

m_originConnection = con

}

void close() throws SQLException {

m_originConnection.close()

}

public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {

Object obj = null

if (CLOSE_METHOD_NAME.equals(m.getName())) {

SimpleConnetionPool.pushConnectionBackToPool(this)

}

else {

obj = m.invoke(m_originConnection, args)

}

lastAccessTime = System.currentTimeMillis()

return obj

}

}

如果你想在action里判断数据库是否链接,只能创建一个标记。全局变量。比如isConn.当创建链接的时候把这个标记设置为1.关闭数据库的时候标记重置 为0.这样在action里不用获取connection对像,直接判断这个全局标记就可以了。

还有就是在创建链接之前先判断这个标记是否是0。在关闭链接之前判断这个标记是否为1


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/6721635.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-27
下一篇 2023-03-27

发表评论

登录后才能评论

评论列表(0条)

保存