Skip to content

OracleLobHandler: Temporary LOBs don't get freed and eat TEMP tablespace [SPR-6209] #10877

Closed
@spring-projects-issues

Description

@spring-projects-issues

Carsten Jahn opened SPR-6209 and commented

We were facing an issue which the temp tablespace being used more and more while CLOBs were fetched in the application.

There are two kinds of LOBs: "ordinary" LOBs and temporary LOBs. Temporary LOBs are constructed on the fly, e.g. while processing a select that appends to LOBs to each other (e.g. molformula || molformula) or functions that create LOBs (e.g. molfile(ctab) returns a temporary CLOB). Temporary CLOBs need to be stored somewhere until they are not needed any more, and they are stored in the TEMP tablespace.

From the Oracle documentation on "Working With Temporary LOBs":
http://download.oracle.com/docs/cd/B28359_01/java.111/b31224/oralob.htm#i1060097
"When fetching data from a ReultSet with columns that are temporary LOBs, use getClob or getBlob instead of getString or getBytes. Also invoke freeTemporary to free the temporary LOBs."

This practice is not implemented in OracleLobHandler. It has methods like

public String getClobAsString(ResultSet rs, int columnIndex) throws SQLException {
logger.debug("Returning Oracle CLOB as string");
Clob clob = rs.getClob(columnIndex);
return (clob != null ? clob.getSubString(1, (int) clob.length()) : null);
}

that should better be implemented that way:

public String getClobAsString(ResultSet rs, int columnIndex) throws SQLException {
logger.debug("Returning Oracle CLOB as string");
oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob(columnIndex);
String returnString = (clob != null ? clob.getSubString(1, (int) clob.length()) : null);
if( clob.isTemporary() ) {
clob.freeTemporary();
}
return returnString;
}

I think that all getClob* / getBlob* methods are affected, although I just tested the change that I pasted above. It works for me, the TEMP tablespace does not get used much and I can fetch large amounts of records with temporary CLOBs - that was not possible before, I just got "ORA-01652: unable to extend temp segment by 128 in tablespace TEMP" after some time.

To reproduce, I think you need a sufficiently small TEMP tablespace, and a SELECT statement that returns large temporary CLOBs, e.g. by appending columns with || and returning the append result.

Without this fix, TEMP tablespace is freed only after Oracle session termination.


Affects: 2.5.6, 3.0 RC1

Issue Links:

Referenced from: commits 5a158fb

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: dataIssues in data modules (jdbc, orm, oxm, tx)type: bugA general bug

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions