Redian新闻
>
问一个可能看起来很怪的问题
avatar
问一个可能看起来很怪的问题# Database - 数据库
f*e
1
我们公司用Oracle。然后用ibm的一个叫record manager的产品
管理纪录。要处理非常大量的表项。产品里有api进行数据添加
和删除。我们写了个ejb每天固定时间做这些操作。可是在极少
数情况下会出现异常退出。看错误信息是由于duplicate relationship
target name。对应于oracle好象是因为有同样表项已经存在。
我看了一下代码,导致出错的代码段是要进行数据库更新,由于
performance的需要,该段代码先在数据库里删除要
添加的表项,然后立刻添加该项。因为直接更新要花比这两个操作
更长的时间(听起来有点怪,但事实如此)。我们数据库里有大量
数据需要进行更新操作,也就是说要做大量先删除紧接着添加。
啰嗦了这么一大堆,我的问题是有没有可能oracle在删除的时候
没有立即commit才导致产生重复项错误。thx.
avatar
B*g
2
can you post oracle error number? ora-xxxxx
BTW, why not use pl/sql to do this job?

【在 f*********e 的大作中提到】
: 我们公司用Oracle。然后用ibm的一个叫record manager的产品
: 管理纪录。要处理非常大量的表项。产品里有api进行数据添加
: 和删除。我们写了个ejb每天固定时间做这些操作。可是在极少
: 数情况下会出现异常退出。看错误信息是由于duplicate relationship
: target name。对应于oracle好象是因为有同样表项已经存在。
: 我看了一下代码,导致出错的代码段是要进行数据库更新,由于
: performance的需要,该段代码先在数据库里删除要
: 添加的表项,然后立刻添加该项。因为直接更新要花比这两个操作
: 更长的时间(听起来有点怪,但事实如此)。我们数据库里有大量
: 数据需要进行更新操作,也就是说要做大量先删除紧接着添加。

avatar
w*r
3
because JAVA is better:D

【在 B*****g 的大作中提到】
: can you post oracle error number? ora-xxxxx
: BTW, why not use pl/sql to do this job?

avatar
f*e
4
抱歉,没看到oracle error number,估计是被ibm的产品吞掉了,
然后wrap起来给了我说的错误。我看到的最接近oracle的错误信息是:
AT com.ibm.gre.engine.dao.oracle.RelationshipORADAO.insert: line -3
这个可能用处不大.
我们用的那个record manager提供了API,所以就没直接用pl/sql。

【在 B*****g 的大作中提到】
: can you post oracle error number? ora-xxxxx
: BTW, why not use pl/sql to do this job?

avatar
I*e
5
Is delete/insert in the same session?

【在 f*********e 的大作中提到】
: 我们公司用Oracle。然后用ibm的一个叫record manager的产品
: 管理纪录。要处理非常大量的表项。产品里有api进行数据添加
: 和删除。我们写了个ejb每天固定时间做这些操作。可是在极少
: 数情况下会出现异常退出。看错误信息是由于duplicate relationship
: target name。对应于oracle好象是因为有同样表项已经存在。
: 我看了一下代码,导致出错的代码段是要进行数据库更新,由于
: performance的需要,该段代码先在数据库里删除要
: 添加的表项,然后立刻添加该项。因为直接更新要花比这两个操作
: 更长的时间(听起来有点怪,但事实如此)。我们数据库里有大量
: 数据需要进行更新操作,也就是说要做大量先删除紧接着添加。

avatar
f*e
6
不好意思,不太明白你说的session具体指什么。
不过这两个操作是同一个程序段紧挨着的两行代码.

【在 I******e 的大作中提到】
: Is delete/insert in the same session?
avatar
I*e
7
Still not sure whether they are in the same session.
Session means your JDBC or ODBC or other interface opens a connection to the
database. If one session delete, the other session insert. Even though
the deleted session committed, the insert session can still see the deleted
row after. This is by design in Oracle.
If you guarantee that your delete/insert are in the same session, you need
to make sure that your commit succeeded.
For update slow issue, it is most likely caused by rollback segm
avatar
c*d
8
“同一个程序段紧挨着的两行代码”
程序是这样的吗?
Connection conn ...;
Statement stmt;
...
stmt.execute("delete ... ");
stmt.execute("insert ... ");
...
stmt.close();
conn.close();
这样的话应该是一个session

【在 f*********e 的大作中提到】
: 不好意思,不太明白你说的session具体指什么。
: 不过这两个操作是同一个程序段紧挨着的两行代码.

avatar
c*d
9
update慢的原因有很多
1. update的表没有索引,或者没有用索引
2. update产生row migration
3. 其他session在更新同样的记录,等待锁的释放
4. 回滚段太小
前两个原因会导致update比delete+insert慢
后两个原因不能导致update比delete+insert慢
将大tranx拆成小tranx,可以减少回滚段的动态extend
不过他们这种情况下问题的症结应该不是回滚段

the
deleted

【在 I******e 的大作中提到】
: Still not sure whether they are in the same session.
: Session means your JDBC or ODBC or other interface opens a connection to the
: database. If one session delete, the other session insert. Even though
: the deleted session committed, the insert session can still see the deleted
: row after. This is by design in Oracle.
: If you guarantee that your delete/insert are in the same session, you need
: to make sure that your commit succeeded.
: For update slow issue, it is most likely caused by rollback segm

avatar
f*e
10
我不是直接用的jdbc调用,而是用ibm那个records manager产品提供的api。
psudo代码是这样的(箭头标出的是和数据库通讯语句。我昨天记错了,不是紧接的
两句,中间有一些无关数据库操作的函数调用):
-> this.DeleteTarget(Id, ... parameters);
try {
OutString = getEmptyStruct;
InputXmlDoc = ChangeToXML(OutString);
PopulatedXMLDoc = PopulateXMLStruct(InputXmlDoc);
InputStr = ChangeToString(PopulatedXmlDoc);
ValidateController();
-> CaseId = InsertTarget(InputStr);
}
我觉得基本上算是同一个session。但不知道ibm的api怎么写的。

【在 c*****d 的大作中提到】
: “同一个程序段紧挨着的两行代码”
: 程序是这样的吗?
: Connection conn ...;
: Statement stmt;
: ...
: stmt.execute("delete ... ");
: stmt.execute("insert ... ");
: ...
: stmt.close();
: conn.close();

avatar
f*e
11
多谢你和InnoBase的回答。这对我分析问题很有帮助。
我们用的这个产品自己管理和设计oracle数据库。所以我也不太清楚是不是
用了索引。
你说的row migration是什么意思?是不是说比如更新的时候导致原来的第三行
变成了第四行?

【在 c*****d 的大作中提到】
: update慢的原因有很多
: 1. update的表没有索引,或者没有用索引
: 2. update产生row migration
: 3. 其他session在更新同样的记录,等待锁的释放
: 4. 回滚段太小
: 前两个原因会导致update比delete+insert慢
: 后两个原因不能导致update比delete+insert慢
: 将大tranx拆成小tranx,可以减少回滚段的动态extend
: 不过他们这种情况下问题的症结应该不是回滚段
:

avatar
c*d
12
Not 更新的时候导致原来的第三行变成了第四行.
Row migration occurs when an update to the row would cause the row not to
fit in the block anymore. The entire row will move to another block. The
original block just has the rowid of the new block.

【在 f*********e 的大作中提到】
: 多谢你和InnoBase的回答。这对我分析问题很有帮助。
: 我们用的这个产品自己管理和设计oracle数据库。所以我也不太清楚是不是
: 用了索引。
: 你说的row migration是什么意思?是不是说比如更新的时候导致原来的第三行
: 变成了第四行?

avatar
I*e
13
I hope that it is not so bad:)
In general, it is uncommon for correct designed schemas.
A way update is slow is because insert can be done with index maintenance
delayed insert. Update can
not do that. Small transactions can alleviate the problem.
avatar
I*e
14
Then, the possibility is whether the delete really deleted all rows to be
inserted. Can you verify that?

【在 f*********e 的大作中提到】
: 我不是直接用的jdbc调用,而是用ibm那个records manager产品提供的api。
: psudo代码是这样的(箭头标出的是和数据库通讯语句。我昨天记错了,不是紧接的
: 两句,中间有一些无关数据库操作的函数调用):
: -> this.DeleteTarget(Id, ... parameters);
: try {
: OutString = getEmptyStruct;
: InputXmlDoc = ChangeToXML(OutString);
: PopulatedXMLDoc = PopulateXMLStruct(InputXmlDoc);
: InputStr = ChangeToString(PopulatedXmlDoc);
: ValidateController();

avatar
f*e
15
可以用程序来验证,但是会影响程序的performance。
不过在我现在找错阶段还是很有用的。不走运的是这种错误
好像很难再现,实在不好查错。

【在 I******e 的大作中提到】
: Then, the possibility is whether the delete really deleted all rows to be
: inserted. Can you verify that?

avatar
B*g
16
can you get alert log from oracle?

【在 f*********e 的大作中提到】
: 可以用程序来验证,但是会影响程序的performance。
: 不过在我现在找错阶段还是很有用的。不走运的是这种错误
: 好像很难再现,实在不好查错。

avatar
f*e
17
我也想问问DBA,可是DBA不是我们公司的,而且不知道有没有这么个log文件。听别人说
好像所有的数据库操作都会产生一个log,不知道是不是这样?

【在 B*****g 的大作中提到】
: can you get alert log from oracle?
avatar
c*d
18
数据库的启动,关闭有一个Log,文本的,可以直接看
数据库的insert/update/delete会写在log file里,这个是2进制的,不能直接看

人说

【在 f*********e 的大作中提到】
: 我也想问问DBA,可是DBA不是我们公司的,而且不知道有没有这么个log文件。听别人说
: 好像所有的数据库操作都会产生一个log,不知道是不是这样?

avatar
c*d
19
你要alert log干吗?
如果是insert duplicate pk,不会写到alert里

【在 B*****g 的大作中提到】
: can you get alert log from oracle?
avatar
f*e
20
谢谢,可是如果插入删除的纪录是二进制的文件该怎么看呢?
是不是有什么工具跟着Oracle来的用于看这种log呢?

【在 c*****d 的大作中提到】
: 数据库的启动,关闭有一个Log,文本的,可以直接看
: 数据库的insert/update/delete会写在log file里,这个是2进制的,不能直接看
:
: 人说

avatar
f*e
21
也许Beijing说的就是你说的那个插入删除的纪录文件。

【在 c*****d 的大作中提到】
: 你要alert log干吗?
: 如果是insert duplicate pk,不会写到alert里

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。