### Cause: java.sql.SQLException: ORA-08103: 对象不再存在
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:23)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:104)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:95)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:59)
原因:
SQL> !oerr ora 08103
08103, 00000, "object no longer exists"
// *Cause: The object has been deleted by another user since the operation
// began, or a prior incomplete recovery restored the database to
// a point in time during the deletion of the object.
// *Action: Delete the object if this is the result of an incomplete
// recovery.
当一个session查询的时候,查询没有结束的时候,另外一个session在truncate表的时候,会导致数据块中的data_object_id 和 数据字典中的data_object_id不匹配,进而报错。
oracle中一般情况下表的OBJECT_ID与DATA_OBJECT_ID是一致的,但在truncate后表达DATA_OBJECT_ID会发生改变。
SQL> col object_name for a40;
SQL> set linesize 500;
SQL> select object_name,object_type,object_id,data_object_id from user_objects where object_name='TT1';
OBJECT_NAME OBJECT_TYPE OBJECT_ID DATA_OBJECT_ID
---------------------------------------- ------------------- ---------- --------------
TT1 TABLE 514640 514640
SQL> truncate table tt1;
Table truncated.
SQL> select object_name,object_type,object_id,data_object_id from user_objects where object_name='TT1';
OBJECT_NAME OBJECT_TYPE OBJECT_ID DATA_OBJECT_ID
---------------------------------------- ------------------- ---------- --------------
TT1 TABLE 514640 514640
SQL> insert into tt1 values(123);
1 row created.
SQL> commit;
Commit complete.
SQL> select object_name,object_type,object_id,data_object_id from user_objects where object_name='TT1';
OBJECT_NAME OBJECT_TYPE OBJECT_ID DATA_OBJECT_ID
---------------------------------------- ------------------- ---------- --------------
TT1 TABLE 514640 514640
SQL> truncate table tt1;
Table truncated.
SQL> select object_name,object_type,object_id,data_object_id from user_objects where object_name='TT1';
OBJECT_NAME OBJECT_TYPE OBJECT_ID DATA_OBJECT_ID
---------------------------------------- ------------------- ---------- --------------
TT1 TABLE 514640 514641
其实object_id和data_object_id同样是表示数据库对象的一个唯一标志,但是object_id表示的是逻辑id,data_object_id表示的是物理id。当表刚创建的时候它的object_id和data_object_id都是相等的,但是如果表经过move或truncate后那么data_object_id将会有变化。
解决办法:
1、用delete代替truncate
2、用select for updaate 查询的时候,将表锁住,不然其他session将表截断。