ORA-01555错误详解
一:zwj;zwj;在电信行业这种数据量巨大的环境中,ora-01555错是一个很常见的错误。这个错误使得应用失败。例如,这一错误可能停
一:
在电信行业这种数据量巨大的环境中,ora-01555错是一个很常见的错误。这个错误使得应用失败。例如,这一错误可能停止一个在深夜运行的批处理任务,随后也使依赖于该任务的其他任务失败。这使用户不能及时得到所需的信息(如报表没打印出来、数据未被导出等等)。尽管这一错误通常发生在大任务上,但在小任务上也会发生。
ORA-1555通常是一个偶然出现的错误。有时在发生了该错误以后,重新运行该任务就有可能不再碰到类似的错误。这个错误最麻烦的是它并不会立刻发生,运行时间长的任务在错误失败以前可能已经运行了一段时间了(可能几个小时)。只是简单地重新运行该任务并不能保证它能成功,可能在运行了一段时间以后仍然失败。
1 原因分析
ORA-1555错的根本原因是因为Oracle要保证读一致性。读一致性是指当有多个用户对一个数据块内的行进行修改时,这些块变“脏”或处于变化之中直到被确认。在被确认以前,它们对事务中的所有语句都是可见的,但是对别的事务或语句而言是不可见的。一旦确认以后,对所有后继的事务或语句就都是可见的了。但在事务被确认前的语句不能看到修改,因为这些修改还未发生。
例如,事务T 1(如对某大表的exp操作)在2 2 :0 0开始而事务T 2(如对同一大表的update操作)在2 2 :0 1时开始,因为T 1需遍历一个很大的表,其读取要花很长的时间,而T 2可能对同一个表中的数据进行基于索引的更新操作。这样, T2可能在几秒钟之内完成,而T 1可能要运行很长时间,假定4 0分钟。当T 1到达T 2做过修改的地方时(根据当前的S C N时间戳可以识别出新作的改变),尽管T 2所进行的写已经被确认,但为了保证读一致性,它不会读到修改后的数据,它只访问在2 2 :0 0时的数据,在2 2 :0 1时所做的改变不能被读取 。T 1从回滚段中读取改变前的数据以保证读一致性。但因为事务T2已经提交,T2事务使用的回滚段oracle认为已经可以重新利用,当回滚段太少或事务较密集时,oracle有可能会用新事务覆盖掉原来T2事务的回滚段,这时T1事务读到被T2修改过的数据时,再从回滚段中就无法找到修改前的数据,这时就会报ORA-1555,snapshot too old错。
下面我们可以结合实例来将此过程回溯一遍:
(1)事务T1在22点开始执行了对某一个大表Test1的exp操作(Test1表数据量可能有几千万甚至更多),那么按照经验,此操作可能需要执行40分钟左右或更长;
(2)事务T2在22点01分开始执行对Test1表某行的update操作,并且操作条件上有索引(将col1为00的行,col2值由90修改为100),故此操作很快完成,比如5秒钟完成操作并commit;
(3)此时事务T2已经执行完毕,而事务T1还在执行中;
(4)当事务T1需要将col1为00的行导出为dmp文件时,Oracle为了保证读一致性,即T1导出的必须是22点时数据库表的值,故col1为00的行对于T1任务来说值仍然为90,而非100;
(5)由于T2事务在22点02分前就已经做完(提交),并且T2认为回滚段是可以重新利用的;
(6)如果此时由于回滚段太少或业务量较密集,oracle就可能会重新利用刚才T2事务所使用的回滚段。这时T1事务读到此处时,就会造成无法找到回滚段中修改前的数据,产生错误。
2 9i中对回滚段管理
在9i中,可以有两种解决方法来维护事务的读一致性,即或者使用自Oracle 6以来就一直使用的回滚段,,或者是使用Undo Tablespace来进行的自动重做管理,但是这两种方法不能同时使用。
考试大建议在9i 中使用回滚表空间而不是8i 的回滚段模式来管理数据库。
(1)建立undotablespace
建立undotablespace的语法如下:
create undotablespace tablespace_name
datafile ’fullpath+datafilename’ size XXM
[autoextend on|off next XX maxsize XX]; 来
二:
写了段java操作数据库的代码
Java代码 String getIPList="select t.dns_ip from t_dnscachetotal t where t.locid=0";
String getLocid="select t3.locid from (select max(t2.ipstart) ipstart,max(t2.ipend) ipend from t_GGMAP_IP t2 where t2.ipstart=query_ip(?) and t1.ipstart=t3.ipstart";
String updateDnsCacheTotal="update t_dnscachetotal t set t.locid=? where t.dns_ip=?";
stmt=con.prepareStatement(getIPList);
rs=pstmt.executeQuery();
String ip;
ResultSet rs2;
int countupdate=0;
while(rs.next()){
ip=rs.getString(1);
pstmt2 = con.prepareStatement(getLocid);
pstmt2.setString(1, ip);
pstmt2.setString(2, ip);
rs2=pstmt2.executeQuery();
int locid=-1;
while(rs2.next()){
locid=rs2.getInt(1); }
pstmt2.close();
rs2.close();
countupdate++;
pstmt2=con.prepareStatement(updateDnsCacheTotal);
pstmt2.setInt(1, locid);
pstmt2.setString(2, ip);
pstmt2.executeUpdate();
pstmt2.close();
}
pstmt.close();
rs.close();
String getIPList="select t.dns_ip from t_dnscachetotal t where t.locid=0"; String getLocid="select t3.locid from (select max(t2.ipstart) ipstart,max(t2.ipend) ipend from t_GGMAP_IP t2 where t2.ipstart=query_ip(?) and t1.ipstart=t3.ipstart"; String updateDnsCacheTotal="update t_dnscachetotal t set t.locid=? where t.dns_ip=?"; pstmt=con.prepareStatement(getIPList); rs=pstmt.executeQuery(); String ip; ResultSet rs2; int countupdate=0; while(rs.next()){ ip=rs.getString(1); pstmt2 = con.prepareStatement(getLocid); pstmt2.setString(1, ip); pstmt2.setString(2, ip); rs2=pstmt2.executeQuery(); int locid=-1; while(rs2.next()){ locid=rs2.getInt(1); } pstmt2.close(); rs2.close(); countupdate++; pstmt2=con.prepareStatement(updateDnsCacheTotal); pstmt2.setInt(1, locid); pstmt2.setString(2, ip); pstmt2.executeUpdate(); pstmt2.close(); } pstmt.close(); rs.close();
大体就这样。。我删了一部分代码。
核心的问题就在于
while(rs.next()){
}
因为rs.next实际上是对oracle某表持续的查询,而在循环中又在不断地update这个表,从而导致了这个1555错误,
ora 1555别人的例子 写道首先了解Oracle在什么情况下会产生ORA-01555错误:

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

蘋果公司最新發布的iOS18、iPadOS18以及macOSSequoia系統為Photos應用程式增添了一項重要功能,旨在幫助用戶輕鬆恢復因各種原因遺失或損壞的照片和影片。這項新功能在Photos應用的"工具"部分引入了一個名為"已恢復"的相冊,當用戶設備中存在未納入其照片庫的圖片或影片時,該相冊將自動顯示。 "已恢復"相簿的出現為因資料庫損壞、相機應用未正確保存至照片庫或第三方應用管理照片庫時照片和視頻丟失提供了解決方案。使用者只需簡單幾步

Hibernate多態映射可映射繼承類別到資料庫,提供以下映射類型:joined-subclass:為子類別建立單獨表,包含父類別所有欄位。 table-per-class:為子類別建立單獨資料表,僅包含子類別特有列。 union-subclass:類似joined-subclass,但父類別表聯合所有子類別列。

PHP處理資料庫連線報錯,可以使用下列步驟:使用mysqli_connect_errno()取得錯誤代碼。使用mysqli_connect_error()取得錯誤訊息。透過擷取並記錄這些錯誤訊息,可以輕鬆識別並解決資料庫連接問題,確保應用程式的順暢運作。

如何在PHP中使用MySQLi建立資料庫連線:包含MySQLi擴充(require_once)建立連線函數(functionconnect_to_db)呼叫連線函數($conn=connect_to_db())執行查詢($result=$conn->query())關閉連線( $conn->close())

在Golang中使用資料庫回呼函數可以實現:在指定資料庫操作完成後執行自訂程式碼。透過單獨的函數新增自訂行為,無需編寫額外程式碼。回調函數可用於插入、更新、刪除和查詢操作。必須使用sql.Exec、sql.QueryRow或sql.Query函數才能使用回呼函數。

可以透過使用gjson函式庫或json.Unmarshal函數將JSON資料儲存到MySQL資料庫中。 gjson函式庫提供了方便的方法來解析JSON字段,而json.Unmarshal函數需要一個目標類型指標來解組JSON資料。這兩種方法都需要準備SQL語句和執行插入操作來將資料持久化到資料庫中。

在C++中使用DataAccessObjects(DAO)函式庫連接和操作資料庫,包括建立資料庫連線、執行SQL查詢、插入新記錄和更新現有記錄。具體步驟為:1.包含必要的函式庫語句;2.開啟資料庫檔案;3.建立Recordset物件執行SQL查詢或操作資料;4.遍歷結果或依照特定需求更新記錄。

透過Go標準庫database/sql包,可以連接到MySQL、PostgreSQL或SQLite等遠端資料庫:建立包含資料庫連接資訊的連接字串。使用sql.Open()函數開啟資料庫連線。執行SQL查詢和插入操作等資料庫操作。使用defer關閉資料庫連線以釋放資源。
