Create Or Replace Package Result_Cache_Test AsOn the package body list the set of tables underlying sql relies on
Function Get_Country_City (In_City In Varchar2, In_Country In Varchar2)
Return Varchar2
result_cache;
end;
/
Create Or Replace Package Body Result_Cache_Test AsTest with PL/SQL Code
Function Get_Country_City(In_City In Varchar2, In_Country In Varchar2)
Return Varchar2
Result_Cache
Relies_On (city,country)
Is
Ret_City Varchar2(200);
ret_country varchar2(200);
Begin
Select Ci.Name,Co.Name Into Ret_City,Ret_Country
From City Ci, Country Co
Where Ci.Country = Co.Code
And Ci.Code = In_City
And Co.Code = In_Country;
return ret_city || ':'||ret_country;
end;
end;
/
set serveroutput onOr to know the effects of Result Cache Latch on concurrent access simulate with java code. Main class
Declare
val varchar2(400);
Begin
Val := Result_Cache_Test.Get_Country_City('SIN','SG');
dbms_output.put_line(val);
end;
/
public class Main {Worker Class
public static void main(String[] args) {
try {
OracleDataSource dataSource = new OracleDataSource();
dataSource.setURL("jdbc:oracle:thin:@url");
dataSource.setUser("username");
dataSource.setPassword("password");
String[][] cities = {{"CMB","LK"},
{"LAX","US"},
{"SIN","SG"},
{"LON","GB"}
};
int loops = 1000;
WorkerThread[] threads = new WorkerThread[400];
String sql1 = "begin ? := result_cache_test.Get_Country_City(?,?); end;";
for (int i = 0 ; i < threads.length ; i++){
threads[i] = new WorkerThread(dataSource.getConnection(), sql1,cities,loops);
}
for(int i = 0 ; i < threads.length; i++){
threads[i].start();
}
} catch (Exception ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class WorkerThread extends Thread {View latch misses, sleeps with
private Connection con;
String sql;
String[][] data;
int loops;
public WorkerThread(Connection con, String sql, String[][] data, int loops) {
this.con = con;
this.sql = sql;
this.data = data;
this.loops = loops;
}
@Override
public void run() {
try {
CallableStatement clm;
for (int i = 0; i < loops; i++) {
clm = con.prepareCall(sql);
clm.registerOutParameter(1, Types.VARCHAR);
clm.setString(2, data[i%4][0]);
clm.setString(3, data[i%4][1]);
clm.execute();
String out = clm.getString(1);
Logger.getLogger(WorkerThread.class.getName()).log(Level.INFO,getName() + " "+out);
clm.close();
}
con.close();
} catch (SQLException ex) {
Logger.getLogger(WorkerThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
select name,gets, misses, sleeps, wait_timeThis test was done on a 4 cpu server on 11gR1 with PSU 11.1.0.7.4 applied.
from V$latch where Name like '%Result%';
NAME GETS MISSES SLEEPS WAIT_TIME
---------------------- ---------- ---------- ---------- ----------
Result Cache: Latch 1576450 13 3 681
Result Cache: SO Latch 2439 5 2 787
As of 11gR2 'relies_on' is deprecated. From PL/SQL Language Ref Guide "Release 11.2, the database detects all data sources that are queried while a result-cached function is running, and relies_on_clause does nothing. This clause is deprecated."