癥狀:系統(tǒng)運(yùn)行了一段時(shí)間報(bào)錯(cuò):java.sql.SQLException: ORA-01000: 超出打開(kāi)游標(biāo)的最大數(shù)
step 1:
查看數(shù)據(jù)庫(kù)當(dāng)前的游標(biāo)數(shù)配置slqplus:show parameter open_cursors;
step 2:
查看游標(biāo)使用情況:
select o.sid, osuser, machine, count(*) num_curs
from v$open_cursor o, v$session s
where user_name = 'user' and o.sid=s.sid
group by o.sid, osuser, machine
order by num_curs desc;
此處的user_name='user'中,user代表占用數(shù)據(jù)庫(kù)資源的數(shù)據(jù)庫(kù)用戶名.
step 3:
查看游標(biāo)執(zhí)行的sql情況:
select o.sid q.sql_text
from v$open_cursor o, v$sql q
where q.hash_value=o.hash_value and o.sid = 123;
step 4:
根據(jù)游標(biāo)占用情況分析訪問(wèn)數(shù)據(jù)庫(kù)的程序在資源釋放上是否正常,如果程序釋放資源沒(méi)有問(wèn)題,則加大游標(biāo)數(shù)。
alter system set open_cursors=2000 scope=both;
補(bǔ)充:在java代碼中,執(zhí)行conn.createStatement()和conn.prepareStatement()的時(shí)候,實(shí)際上都是相當(dāng)與在數(shù)據(jù)庫(kù)中打開(kāi)了一個(gè)cursor。尤其是,如果你的createStatement和prepareStatement是在一個(gè)循環(huán)里面的話,就會(huì)非常容易出現(xiàn)這個(gè)問(wèn)題。因?yàn)橛螛?biāo)一直在不停的打開(kāi),而且沒(méi)有關(guān)閉。
一般來(lái)說(shuō),我們?cè)趯慗ava代碼的時(shí)候,createStatement和prepareStatement都應(yīng)該要放在循環(huán)外面,而且使用了這些Statment后,及時(shí)關(guān)閉。最好是在執(zhí)行了一次executeQuery、executeUpdate等之后,如果不需要使用結(jié)果集(ResultSet)的數(shù)據(jù),就馬上將Statment關(guān)閉,調(diào)用close()方法。