oracle查询未释放连接的sql

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle查询未释放连接的sql相关的知识,希望对你有一定的参考价值。

最近发现程序不知在什么地方没有关闭连接,导致超出数据库连接最大数,连接不上数据库了,我像查下是那条sql语句没有正常关闭连接造成的,怎么查询,请大侠多多帮忙!

用如下语句查询未释放连接的sql。

select object_name,machine,s.sid,s.serial# from v$locked_object l,dba_objects o ,v$session s where l.object_id = o.object_id and l.session_id=s.sid;

如图,就是查看未释放连接的语句的sid等内容。

参考技术A A(港口表)港口代码 港口名B(船抵达港口表)船名 抵港港口代码 预抵港口代码暂且设这两个名和这些个字段吧select a.船名,b.港口名 抵港港口名,c.港口名 预抵港口名 from 船抵达港口表 a,港口表 b,港口表 c wherea.抵港港口代码=b.港口代码 and a.预抵港口代码=c.港口代码就是把第1个表拿出来用两次,分别和那个表关联 参考技术B 比较复杂,得查程序代码,如果连接是程序中open 的必须 程序close 否则就不会自动关闭连接,如果是sqladapter 自动打开的不需要close ,逐行查代码吧,没有什么好办法。 参考技术C select logon_time,last_call_et,username,status,t2.SQL_TEXT from V$session t1 left join v$sql t2 on t1.PREV_SQL_ID=t2.SQL_ID where username='此处为数据库连接用户'  order by username,logon_time,last_call_et追问

好像不行啊,就第一次登录的记录显示了,然后我在一个小程序中故意没有关闭连接,但是没显示出来,不知怎么回事?

参考技术D 你确定是数据库连接没关闭

你可以用pl/sql查询oracle会话看那个sql的会话最多啊本回答被提问者和网友采纳

在 Spring Boot 和 Oracle 中使用 STRUCTS 时未释放连接

【中文标题】在 Spring Boot 和 Oracle 中使用 STRUCTS 时未释放连接【英文标题】:Connections not being released when using STRUCTS in Spring Boot and Oracle 【发布时间】:2017-09-14 14:11:30 【问题描述】:

我有一个 Spring Boot 应用程序,我在其中托管了多个 REST 和 SOAP WebServices。我客户的最新请求是执行一个存储过程,该过程接收多个参数和 3 个自定义数组。

它似乎工作正常,但在执行 5 次后,我收到以下错误:

超时:池为空。无法在 30 秒内获取连接,无可用 [size:5;忙:5;空闲:0;最后等待:30000]。

我不明白为什么在使用此特定功能时连接没有被释放。

我正在从 Spring 扩展 StoredProcedure

public class OracleArrayStoredProcedure extends StoredProcedure 

在那之后,我有一堆最终的字符串作为我的参数(超过 50 个),然后我有了构造函数:

public OracleArrayStoredProcedure(DataSource ds) 
        super(ds, PROC_NAME);

在构造函数中我有参数,其中还包括数组:

declareParameter(new SqlParameter(PARAM1, OracleTypes.NUMBER));

        // Arrays
        declareParameter(new SqlInOutParameter(ARRAY1, OracleTypes.ARRAY, "ARRAY1"));
        declareParameter(new SqlInOutParameter(ARRAY2, OracleTypes.ARRAY, "ARRAY2"));
        declareParameter(new SqlInOutParameter(ARRAY3, OracleTypes.ARRAY, "ARRAY3"));
        compile();

然后我执行,这是我无法释放的连接:

public ArrayResponse execute(ArrayRequest arrayRequest) 

        ArrayResponse response = new ArrayResponse();
        Map<String, Object> inputs = new HashMap<String, Object>();
        try 

            OracleConnection connection = getJdbcTemplate().getDataSource().getConnection()
                    .unwrap(OracleConnection.class);

            // ARRAY1
            ArrayDescriptor arrayFirstDescriptor = new ArrayDescriptor(ARRAY1, connection);
            StructDescriptor recFirstDescriptor = new StructDescriptor("FIRSTREC", connection);

            Object[] arrayFirstStruct = new Object[arrayRequest.getArray1().size()];
            int i = 0;
            for (Iterator<Array1> iterator = arrayRequest.getArray1().iterator(); iterator
                    .hasNext();) 
                Model1 model1 = (Model1) iterator.next();
                STRUCT s = new STRUCT(arrayFirstDescriptor, connection, new Object[]  
// Bunch of attributes
                arrayStructArray[i++] = s;
            
            ARRAY inStructArray = new ARRAY(arrayDescriptor, connection, array1Struct);

最后我将数组和参数放入输入映射并执行它:

        inputs.put(ARRAY1, inStructArray);
        Map<String, Object> out = super.execute(inputs);

这种方法的问题是我无法释放连接(即使我使用了 connection.close()),所以在 5 次执行后它不再起作用。我做错了什么?

当我不必使用 STRUCT 时,我不需要使用

OracleConnection connection = getJdbcTemplate().getDataSource().getConnection()
                        .unwrap(OracleConnection.class);

所以一切正常。

【问题讨论】:

它们没有被释放,因为它们不受 Spring 控制。您正在自己打开/请求新的连接,因此应该自己关闭它们。基本上,如果你开始做getJdbcTemplate().getDataSource().getConnection() 之类的事情,那么请从你的键盘上退后并重新考虑。而是使用 Spring 中的 ConnectionCallback 这是我能找到的唯一可行的例子。你能指出我正确的方向吗?我想把它做好 我已经为您指明了正确的方向,请使用ConnectionCallback 【参考方案1】:

我可以通过实现 AbstractSqlTypeValue() 来修复它,它有一个传递 DataSource 连接的方法。这样,我不必手动获取连接。然后我只需将 structArray 添加到输入映射中。

SqlTypeValue structArray = new AbstractSqlTypeValue() 
                @Override
                protected Object createTypeValue(Connection connection, int arg1, String arg2) throws SQLException 
                    Object[] modelArray = new Object[request.getArray().size()];
                    int i = 0;
                    for (Iterator<Model> iterator = request.getArray().iterator(); iterator.hasNext();) 
                        Model model = (Model) iterator.next();
                        Struct s = connection.createStruct("TEST_REC", new Object[]  
                          // All attributes go here
                        );
                        modelArray[i++] = s;
                    
                    Array structArray = ((OracleConnection) connection).createOracleArray("TEST_STRUCT",
                            modelArray);
                    return structArray ;
                
            ;

【讨论】:

以上是关于oracle查询未释放连接的sql的主要内容,如果未能解决你的问题,请参考以下文章

SQL Oracle中子查询的工作

oracle怎么强制断开数据库连接。

oracle数据库用了定时器查询数据库,每一分钟查询一次,一段时间后导致数据库最大连接数太大

包含左连接的 SQL Oracle 更新

oracle连接数过多 如何释放

oracle做分页查询怎么做?