`
nickkathy
  • 浏览: 34639 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

检查 数据库锁和程序没有释放数据库连接

    博客分类:
  • java
阅读更多
SELECT /*+ rule*/
B.INST_ID,
A.EVENT,
C.SID,
B.SPID,
C.MACHINE,
C.SECONDS_IN_WAIT,
'kill -9 ' || B.SPID,
'alter system kill session '''||C.SID||','||C.SERIAL#||''';',
E.OBJECT_NAME,
dbms_rowid.ROWID_CREATE(1,C.ROW_WAIT_OBJ#,C.ROW_WAIT_FILE#,C.ROW_WAIT_BLOCK#,C.ROW_WAIT_ROW#) RWID,
D.SQL_TEXT
  FROM GV$SESSION_WAIT A,
       GV$PROCESS      B,
       GV$SESSION      C,
       GV$SQLAREA      D,
       DBA_OBJECTS     E
WHERE A.EVENT = 'enq: TX - row lock contention'
   AND A.SID = C.SID
   AND C.PADDR = B.ADDR
   AND A.INST_ID = C.INST_ID
   AND A.INST_ID = B.INST_ID
   AND A.INST_ID = D.INST_ID
   AND C.SQL_ID = D.SQL_ID(+)
   AND C.ROW_WAIT_OBJ# = E.OBJECT_ID
--  AND A.INST_ID = 2
ORDER BY INST_ID, SECONDS_IN_WAIT DESC;

select s.SID,s.MACHINE,s.USERNAME,s.STATUS,s.LOGON_TIME,s2.SQL_TEXT from v$session s,v$sqlarea s2
where s.SQL_ID = s2.SQL_ID
order by s.LOGON_TIME desc

----------------以下转帖备份--------------
1.利用oracle数据库的动态性能视图v$open_cursor,即通过游标来查找未释放的数据库连接

select * from v$open_cursor where user_name='SCOTT';其中SCOTT为登录的用户名

如果java数据库的连接没有关闭通过上面的sql语句就可以看到被查询的sql语句 select * from dept

在被打开的游标里面出现多次。如下所示:

123 3997DA58 315 SCOTT 39F2EAFC 2979176267 01uk0fqst57ub select * from dept
120 39976A20 309 SCOTT 39F2EAFC 2979176267 01uk0fqst57ub select * from dept
124 3996F9E8 303 SCOTT 39F2EAFC 2979176267 01uk0fqst57ub select * from dept

然后根据sql语句去查找,写java代码是那个sql语句没有关闭。

2.通过proxool数据库连接池来查找

首先建立一个web project工程testProxool,创建一个cfg包创建LoadDbXml.java类内容如下:

package cfg;

import java.util.*;
import java.io.*;

import org.jdom.*;
import org.jdom.input.SAXBuilder;
import org.logicalcobwebs.proxool.ProxoolException;
import org.logicalcobwebs.proxool.ProxoolFacade;

public class LoadDbXml {

private Element rootElement = null;
public static HashMap sqlEle = new HashMap();
//初始化构造方法
public LoadDbXml(){
   String proxool = "D:\\MyEclipse\\workspace\\testCharacter\\WebRoot\\WEB-INF\\proxool.xml";
   getRootElement(proxool);
   initDBConn(proxool);
}
//获得根节点
public void getRootElement(String m_xmlFilePath)
{
   Document doc = null;
   try{
    File file = null;
    file = new File(m_xmlFilePath);
    SAXBuilder sb = new SAXBuilder();
    doc = sb.build(file);
    rootElement = doc.getRootElement();
   }catch(Exception ex){
    ex.printStackTrace();
   }
}
//初始化数据库参数
public void initDBConn(String m_xmlFilePath)
{
   Element ele = rootElement.getChild("database");
   try{
    Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
    Properties info = new Properties();
    info.setProperty("proxool.maximum-connection-count", ele.getChildText("DBPoolMaxConnection"));
    info.setProperty("proxool.minimum-connection-count", ele.getChildText("DBPoolMinConnection"));
    info.setProperty("proxool.maximum-active-time", ele.getChildText("DBPoolTimeoutValue"));
    info.setProperty("proxool.maximum-connection-lifetime", ele.getChildText("DBPoolTimeoutValue"));
    info.setProperty("proxool.prototype-count", ele.getChildText("DBPoolPrototypeCount"));
    info.setProperty("proxool.trace", "true");
    info.setProperty("user", ele.getChildText("DBUser"));
    info.setProperty("password", ele.getChildText("DBPassword"));
             
    String url = "proxool." + ele.getChildText("DBAlias") + ":" + ele.getChildText("DBDrivername") + ":" + ele.getChildText("DBDriverurl");
    ProxoolFacade.registerConnectionPool(url, info);
   }catch (ProxoolException e) {
    e.printStackTrace();
   }catch (ClassNotFoundException e) {
    e.printStackTrace();
   }
}
}

创建一个servlet类,用于启动web工程时初始化数据库InitDbXml

package cfg;

import javax.servlet.http.HttpServlet;
import javax.servlet.ServletConfig;

public class InitDbXml extends HttpServlet{

/**
* 初始化servlet,调用初始化数据库类
*/
private static final long serialVersionUID = 1L;

public void init(ServletConfig config){
   new LoadDbXml();
}
}
在WEB-INF下创建一个proxool.xml文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<dbconfig>
<database>
   <DBSMType>ORACLE</DBSMType>
   <DBAlias>eomsdb</DBAlias>
   <DBDrivername>oracle.jdbc.driver.OracleDriver</DBDrivername>
   <DBDriverurl>jdbc:oracle:thin:@192.168.20.92:1521:chshsid</DBDriverurl>
   <DBUser>scott</DBUser>
   <DBPassword>tiger</DBPassword>
   <DBPoolName>orpool</DBPoolName>
   <DBPoolMinConnection>1</DBPoolMinConnection>
   <DBPoolPrototypeCount>1</DBPoolPrototypeCount>
   <DBPoolMaxConnection>3</DBPoolMaxConnection>
   <DBPoolTimeoutValue>20000</DBPoolTimeoutValue>
</database>
</dbconfig>

在web.xml文件里面加入以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!--将采用的字符编码配置成应用初始化参数而不是过滤器私有的初始化参数是因为在JSP和其他地方也可能需要使用-->

<!-- 连接池的监控环境开始,项目部署时要删除 -->
   <servlet>
     <servlet-name>proxooladmin</servlet-name>
     <servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
   </servlet>
   <servlet-mapping>
     <servlet-name>proxooladmin</servlet-name>
     <url-pattern>/dbadmin</url-pattern>
   </servlet-mapping>
<!-- 连接池的监控环境结束-->
<!-- 初始化数据库连接start -->
<servlet>
   <servlet-name>initDbXml</servlet-name>
   <servlet-class>cfg.InitDbXml</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>

<!-- 初始化数据库连接end -->
</web-app>
在\WebRoot\admin下新建两个jsp文件closeConn.jsp内容如下:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page import="java.sql.*" %>
<%@ page import="cfg.LoadDbXml"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <base href="<%=basePath%>">
    <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">   
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>&nbsp;
<%
      PreparedStatement ps = null;
      Connection conn = null;
      ResultSet rs = null;
   try {
    conn = DriverManager.getConnection("proxool.eomsdb");
    ps = conn.prepareStatement(" select * from emp ");
    rs = ps.executeQuery();
    out.println("<table bgcolor='green' border='1' width='400' height='500'>");
    while(rs.next()){
     out.println("<tr><td>" + rs.getString(1)+"</td><td>" + rs.getString(2) + "</td></tr>");
    }
    out.println("</table>");
   } catch (SQLException e){
    e.printStackTrace();
   }finally{
    if(rs!=null)
     rs.close();
    if(ps!=null)
     ps.close();
    if(conn!=null)
     conn.close();
   }
   %>
</body>
</html>
创建没有关闭数据库连接的jsp文件noCloseConn.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page import="java.sql.*" %>
<%@ page import="cfg.LoadDbXml"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <base href="<%=basePath%>">
    <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">   
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>&nbsp;
<%
      PreparedStatement ps = null;
      Connection conn = null;
      ResultSet rs = null;
   try {
    conn = DriverManager.getConnection("proxool.eomsdb");
    ps = conn.prepareStatement(" select * from dept ");
    rs = ps.executeQuery();
    out.println("<table bgcolor='green' border='1' width='400' height='500'>");
    while(rs.next()){
     out.println("<tr><td>" + rs.getString(1)+"</td><td>" + rs.getString(2) + "</td></tr>");
    }
    out.println("</table>");
   } catch (SQLException e) {
    e.printStackTrace();
   }
   //数据库没有进行连接
   %>
</body>
</html>


我在proxool.xml文件设置了最大连接数为3

如果http://localhost:8080/testProxool/admin/noCloseConn.jsp该页面连续被刷新四次,后台就会报出错误,
java.sql.SQLException: Couldn't get connection because we are at maximum connection count (3/3) and there are none available
at org.logicalcobwebs.proxool.Prototyper.quickRefuse(Prototyper.java:309)
at org.logicalcobwebs.proxool.ConnectionPool.getConnection(ConnectionPool.java:152)
at org.logicalcobwebs.proxool.ProxoolDriver.connect(ProxoolDriver.java:89)
at java.sql.DriverManager.getConnection(DriverManager.java:525)

我们访问http://localhost:8080/testProxool/dbadmin连接就会发现在

Proxool 0.9.1 (23-Aug-2008 11:10)
Definition
Snapshot
alias: eomsdb
Start date: 2010-06-15 18:55:01
Snapshot: 19:14:59
Connections: 3 (active), 0 (available), 3 (max)


Served: 38
Refused: 73
Details:
(click ID to drill down) # born last
start lap
(ms) thread
41 19:14:56 19:14:56 3093   http-8080-Processor25
40 19:14:56 19:14:56 3312   http-8080-Processor23
39 19:14:53 19:14:56 3859   http-8080-Processor23

Connection #41 sql = select * from dept ;proxy = bdb6aedelegate = 12478a9url = jdbc:oracle:thin:@192.168.20.92:1521:chshsid



访问select * from dept ; sql语句没有断开数据库连接,可以根据sql语句找到相应的java类。

问题便可以轻易的解决,可以不用自己手工写数据库连接池,来用proxool连接池,这个被公认的比较好的数据库连接池。




分享到:
评论

相关推荐

    Java jdbc数据库连接池总结

    连接池的基本工作原理是:当应用程序需要建立数据库连接时,连接池管理器会检查当前是否有可用的连接,如果有,则返回一个可用的连接对象;否则,连接池管理器将创建一个新的连接对象,并将其添加到连接池中。应用...

    jsp连接数据库连接池代码示例

    数据库连接池是一种管理数据库连接的技术,它预先初始化一定数量的数据库连接并保存在内存中,当应用程序需要连接数据库时,可以从连接池中获取一个已存在的连接,用完后再归还,而不是每次都新建和关闭连接。...

    delphi实现数据库连接池

    在Delphi这个强大的Windows应用程序开发环境中,实现数据库连接池能够有效地解决频繁创建和销毁数据库连接带来的性能问题。下面我们将详细探讨如何在Delphi中实现数据库连接池,以及其核心概念和优势。 数据库连接...

    c语言连接达梦MD数据库

    总的来说,C语言连接达梦数据库的过程涉及ODBC接口的使用,配置DSN,编写连接和查询代码,以及在VS2013中的项目设置。通过学习和实践这些步骤,开发者可以构建自己的C语言应用程序,实现与达梦数据库的有效交互。...

    数据库连接池原理

    - 当执行一个SQL命令时,如果没有连接池,那么每次都需要经历完整的连接和断开过程,这包括TCP连接的三次握手、数据库认证的三次握手、SQL执行、数据库关闭以及TCP的四次挥手关闭。这种方式虽然实现简单,但是存在...

    数据库连接池的图解原理

    数据库连接池是现代应用程序开发中的一个关键组件,它在提高数据库访问效率、管理资源和优化系统性能方面扮演着重要角色。本文将详细解释数据库连接池的图解原理,帮助你理解这一技术的核心概念。 首先,我们需要...

    数据库连接池java代码实现

    数据库连接池在Java中的实现是提高应用程序性能的关键技术之一,它通过复用已存在的数据库连接,避免了频繁创建和销毁连接导致的系统资源浪费。本文将深入探讨如何使用Java代码来实现一个简单的数据库连接池,并解释...

    数据库连接池 java 整理

    这些库提供了管理和维护数据库连接的功能,包括初始化连接池、获取和释放连接、自动关闭连接以及监控连接状态。 Oracle数据库是世界上最广泛使用的商业关系型数据库之一,特别适合于大型企业级应用。在Java中与...

    数据库连接池代码

    数据库连接池是现代Java应用程序中不可或缺的组件,它在提高应用程序性能、管理和优化数据库资源方面起着关键作用。本文将深入探讨基于JDBC的数据库连接池技术,主要针对Oracle数据库,但很多概念同样适用于其他...

    delphi数据库连接池

    Delphi数据库连接池是一种高效的数据库资源管理技术,它允许应用程序在多用户环境下共享数据库连接,以提高性能并减少系统资源的消耗。连接池的核心思想是重用已建立的数据库连接,而不是每次需要时都创建新的连接,...

    java数据库连接池

    而这个`jdbcPool.jar`库,作为手写实现,可能没有那么丰富的功能,但它的存在为学习和理解数据库连接池的工作机制提供了很好的实践案例。 在`readme.txt`文件中,通常会包含关于如何使用这个库的详细说明,包括如何...

    java数据库连接池笔记

    Java数据库连接池是一种管理数据库连接的技术,用于高效地管理和复用数据库连接,从而提高应用程序的性能和资源利用率。连接池的基本思想是在应用启动时预先创建一定数量的数据库连接,存储在一个池中,当应用程序...

    数据库连接池代码实现

    数据库连接池是现代应用程序开发中的重要组成部分,尤其是在处理大量数据交互的应用中,它极大地提高了数据库操作的效率和系统的稳定性。数据库连接池的概念是预先创建并维护一定数量的数据库连接,这些连接可以被多...

    java写的数据库连接池

    首先,数据库连接池是管理数据库连接的一种机制,它允许应用程序重复使用已建立的数据库连接,而不是每次需要时都创建新的连接。这种方式可以显著提高性能,减少资源消耗,因为创建和销毁数据库连接的过程是昂贵的。...

    java 连接数据库实现用户登录功能

    5. **关闭资源**:完成操作后,记得关闭`ResultSet`,`PreparedStatement`和`Connection`以释放数据库资源: ```java rs.close(); pstmt.close(); conn.close(); ``` 为了实现登录界面,你可以使用Java Swing...

    java web测试数据库连接是否正常

    在Java Web开发中,数据库连接是至关重要的环节,它确保了应用程序能够与数据存储进行有效交互。...正确配置数据库连接参数,使用JDBC API进行连接和查询,是确保应用程序与数据库间通信畅通无阻的基础。

    C# 数据库连接池实例

    连接池的基本工作原理是:当应用程序请求一个新的数据库连接时,连接池会检查是否存在可重用的、已关闭但尚未被清除的连接。如果有,就直接返回这个连接,否则创建一个新的连接并添加到池中。当连接不再使用时,它并...

    Power Builder同时连接多个数据库

    4. **异常处理**:通过条件语句检查连接状态,如果失败则显示错误消息,并执行回滚操作以释放资源。 #### 结论 通过以上示例可以看出,在PowerBuilder中同时连接多个数据库是完全可行的。关键是要正确配置数据库...

    winform数据库连接池源码

    1. **初始化连接池**:在应用程序启动时,数据库连接池会自动初始化,设置初始连接数和最大连接数。初始连接数通常较小,以节省资源;最大连接数限制了同时打开的数据库连接数,防止资源耗尽。 2. **连接检查与回收...

Global site tag (gtag.js) - Google Analytics