Sql 异常ORA-08103:在使用Hibernate的setfetchsize时,对象不再存在
我正在使用Hibernate。我需要获取大约1000000条记录,这将导致超时异常。因此,我对6000条记录使用setfetchsize,这样它将在6000条记录中的多个事务中分发操作 大约需要21个小时才能取回所有 但在检索记录的同时,如果有人删除了要获取的其中一条记录,那么我得到的ORA-08103:object就不存在了Sql 异常ORA-08103:在使用Hibernate的setfetchsize时,对象不再存在,sql,oracle,hibernate,exception,Sql,Oracle,Hibernate,Exception,我正在使用Hibernate。我需要获取大约1000000条记录,这将导致超时异常。因此,我对6000条记录使用setfetchsize,这样它将在6000条记录中的多个事务中分发操作 大约需要21个小时才能取回所有 但在检索记录的同时,如果有人删除了要获取的其中一条记录,那么我得到的ORA-08103:object就不存在了 现在我想跳过在检索时删除的对象。如何执行此操作?很可能是基于全局临时表GTT打开了光标,全局临时表GTT是使用“提交-删除行”选项创建的。ORA-08103:object
现在我想跳过在检索时删除的对象。如何执行此操作?很可能是基于全局临时表GTT打开了光标,全局临时表GTT是使用“提交-删除行”选项创建的。ORA-08103:object不再存在错误的原因是紧跟在delete语句之后的commit语句。下面是一个简单的例子:
SQL> declare
2 type t_recs is table of number;
3 l_cur sys_refcursor; -- our cursor
4 l_rec t_recs;
5
6 begin
7
8 -- populating a global temporary table GTT1 with sample data
9 insert into GTT1(col)
10 select level
11 from dual
12 connect by level <= 1000;
13
14 open l_cur -- open a cursor based on data from GTT1
15 for select col
16 from GTT1;
17
18 -- here goes delete statement
19 -- and
20 commit; <-- cause of the error. After committing all data from GTT1 will be
21 -- deleted and when we try to fetch from the cursor
22 loop -- we'll face the ORA-08103 error
23 fetch l_cur -- attempt to fetch data which are long gone.
24 bulk collect into l_rec;
25 exit when l_cur%notfound;
26 end loop;
27
28 end;
29 /
ORA-08103: object no longer exists
ORA-06512: at line 24
使用on commit preserve rows子句重新创建全局临时表将允许从基于该表的游标安全地获取数据,而不必担心遇到ORA-08103:错误。经过一周的努力,我终于解决了这个问题: 解决方案:很可能是基于全局临时tableGTT打开了游标,该tableGTT是使用on COMMIT DELETE ROWS选项创建的。ORA-08103:object不再存在错误的原因是紧跟在delete语句之后的commit语句。DBA团队不同意将GTT更改为提交保留行,所以最后我在Java服务层中添加了代码库[实现Spring编程事务]
package com.test;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
public class StudentJDBCTemplate implements StudentDAO {
private DataSource dataSource;
private JdbcTemplate jdbcTemplateObject;
private PlatformTransactionManager transactionManager;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
this.jdbcTemplateObject = new JdbcTemplate(dataSource);
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public void create(String name, Integer age, Integer marks, Integer year){
TransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(def);
try {
String SQL1 = "insert into Student (name, age) values (?, ?)";
jdbcTemplateObject.update( SQL1, name, age);
// Get the latest student id to be used in Marks table
String SQL2 = "select max(id) from Student";
int sid = jdbcTemplateObject.queryForInt( SQL2 );
String SQL3 = "insert into Marks(sid, marks, year) " + "values (?, ?, ?)";
jdbcTemplateObject.update( SQL3, sid, marks, year);
System.out.println("Created Name = " + name + ", Age = " + age);
transactionManager.commit(status);
}
catch (DataAccessException e) {
System.out.println("Error in creating record, rolling back");
transactionManager.rollback(status);
throw e;
}
return;
}
public List<StudentMarks> listStudents() {
String SQL = "select * from Student, Marks where Student.id=Marks.sid";
List <StudentMarks> studentMarks = jdbcTemplateObject.query(SQL,
new StudentMarksMapper());
return studentMarks;
}
}
不知道您要做什么的上下文,但是为什么您必须使用hibernate,并且没有直接sql或pl/sql调用。会快得多。我无法替换Hibernate,因为它会增加项目的时间消耗。我的问题是,在执行executeQuery时,oracle将抛出ORA-08103:对象不再存在异常,因为有人删除了我使用executeQuery获取的记录。现在,我在获取记录时无法阻止任何人删除一行,因此我需要一些技术,使oracle不会对已删除的记录引发异常,而是应该跳过该记录并继续下一条记录。@Prashant。为什么要在应用程序中获取一百万行?在我看来,有机会在数据库中进行额外的处理,节省了大量的时间。你认为还有其他解释吗?我开始在大插入时出现此错误,只是一个简单的插入。。从视图中选择不发生删除的表。有可能另一个进程正试图截断它下面的表,但原始表应该被锁定,这将防止这种情况发生。@Ben如果在执行insert select语句时截断表,是的,您将得到相同的错误,因为select语句是游标,truncate语句,因为它是一个DDL语句,所以会导致双重提交——在截断之前,然后在截断之后;谢谢你,尼古拉斯。我必须追踪那个流氓程序然后。。。