oracle10g的Dblink的问题ORA-02020

gejigang2006 2011-12-10 11:32:38

for(){单独的update tab@dblinka事务 每次都提交}
报这个错
Caused by: java.sql.SQLException: ORA-02020: 过多的数据库链接在使用中
网上查的这个,alter system set open_links=10scope=spfile; 可是我的循环到第10次又报错了
把open_links改为10000可以吗?会有问题吧,还有如果我不把update做为一个单独的事务来处理
好像没有问题不过问题就出现了,如果其他事务再次提交事务不能关闭dblink,
如果次数多了,是不是会出现问题,现在很是费解提交了事务为什么不能关闭dblink.
哪位牛人指点一下!
...全文
693 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
舞台中央的我 2012-10-10
  • 打赏
  • 举报
回复
oracle 学习了
gejigang2006 2011-12-11
  • 打赏
  • 举报
回复
SmallTransHolder.trans.newTransExecute 是一个单独的事务 里面有commit,
好吧,现在做一次需求,这是一个与其他公司数据库间的中间表,他们在上存大是数据我们拿到数据,再对这张表进行更新,数据量是比较大的,还有这是一个定时任务,每隔一段时间就得去看一下是否有数据更新,
现在的做法是直接去拿数据就是那个
daoSupport.query(sqlstr);//也是一个从Dblink拿数据的select
拿到数据之后,我进行相关保存等操作再回写,为了防止意外,所以把这期间保存等操作与update放在同一个事务里,commit。 因为是数据量大所以分批操作了,就是那个循环,还有因为数据有可能更新,于是做了一个自动任务,是整个方法的外层做的,来调用这个方法,,
出现了这个情况之后呢,我建立了一张本地中间表cache与上面那个中间表完所一样,刚一开始自动任务就去更新本地cache中间表看是否有数据更新,然后才是for()对本地表cache进行相关操作,for()循环完成之后,再去从中间表cache中拿出更新过的数据去更新外面那个中间表,
这样应该OK了,可是出现了问题自动任务会每隔一段时间来调用这个方法 ,也许是因为我设置的间隔时间比较短60秒,还是报上面数据连接过多,超级无语了,本地数据库与中间库之间明明只有一个Dblink为什么oracle为什么认为是不同的呢,还有我用的是
<!-- 多数据源定义 以下是以sql数据库举例 -->
<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
destroy-method="close">
<property name="uniqueResourceName" value="OracleXADataSource" />
<property name="xaDataSourceClassName" value="oracle.jdbc.xa.client.OracleXADataSource" />
<property name="poolSize" value="3" />
<property name="maxPoolSize" value="100" />
<property name="minPoolSize" value="1" />
<property name="xaProperties">
<props>
<prop key="user">orcl</prop>
<prop key="password">1</prop>
<prop key="URL"> jdbc:oracle:thin:@localhost:1521:orcl</prop>
</props>
</property>
<property name="testQuery" value="select 1 from dual" />
</bean>

[Quote=引用 5 楼 wallace_jjh 的回复:]
不好意思,这个“SmallTransHolder.trans.newTransExecute”是启动事务吗?
如果是开启事务,把他放到for外层试试。
[/Quote]
gejigang2006 2011-12-11
  • 打赏
  • 举报
回复
SmallTransHolder.trans.newTransExecute 是一个单独的事务 里面有commit,
好吧,现在做一次需求,这是一个与其他公司数据库间的中间表,他们在上存大是数据我们拿到数据,再对这张表进行更新,数据量是比较大的,还有这是一个定时任务,每隔一段时间就得去看一下是否有数据更新,
现在的做法是直接去拿数据就是那个
daoSupport.query(sqlstr);//也是一个从Dblink拿数据的select
拿到数据之后,我进行相关保存等操作再回写,为了防止意外,所以把这期间保存等操作与update放在同一个事务里,commit。 因为是数据量大所以分批操作了,就是那个循环,还有因为数据有可能更新,于是做了一个自动任务,是整个方法的外层做的,来调用这个方法,,
出现了这个情况之后呢,我建立了一张本地中间表cache与上面那个中间表完所一样,刚一开始自动任务就去更新本地cache中间表看是否有数据更新,然后才是for()对本地表cache进行相关操作,for()循环完成之后,再去从中间表cache中拿出更新过的数据去更新外面那个中间表,
这样应该OK了,可是出现了问题自动任务会每隔一段时间来调用这个方法 ,也许是因为我设置的间隔时间比较短60秒,还是报上面数据连接过多,超级无语了,本地数据库与中间库之间明明只有一个Dblink为什么oracle为什么认为是不同的呢,还有我用的是
<!-- 多数据源定义 以下是以sql数据库举例 -->
<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
destroy-method="close">
<property name="uniqueResourceName" value="OracleXADataSource" />
<property name="xaDataSourceClassName" value="oracle.jdbc.xa.client.OracleXADataSource" />
<property name="poolSize" value="3" />
<property name="maxPoolSize" value="100" />
<property name="minPoolSize" value="1" />
<property name="xaProperties">
<props>
<prop key="user">orcl</prop>
<prop key="password">1</prop>
<prop key="URL"> jdbc:oracle:thin:@localhost:1521:orcl</prop>
</props>
</property>
<property name="testQuery" value="select 1 from dual" />
</bean>

[Quote=引用 5 楼 wallace_jjh 的回复:]
不好意思,这个“SmallTransHolder.trans.newTransExecute”是启动事务吗?
如果是开启事务,把他放到for外层试试。
[/Quote]
gejigang2006 2011-12-10
  • 打赏
  • 举报
回复
我是程序级的,关键的问题是这个事务提交了他为什么 没有close 当我再次打开时他认为是又一个新的dblink呢,在这个循环外还用到dblink如果提交没有close不是很恐怖吗!
[Quote=引用 1 楼 luiseradl 的回复:]
ora-02020错误:就是打开过多的dblink。
解决:
1. 修改init.ora中open_links的值,但改成10000,肯定不可取.
2. 释放一些dblinks,通过提交、回滚和关闭打开的光标。

你虽然commit了,但可能还有光标引用远程数据库吧,光标用完要close
再有,不必每次update都commit,可以在整个for循环结束之后,一次性commit。

……
[/Quote]
我心飞翔 2011-12-10
  • 打赏
  • 举报
回复
ora-02020错误:就是打开过多的dblink。
解决:
1. 修改init.ora中open_links的值,但改成10000,肯定不可取.
2. 释放一些dblinks,通过提交、回滚和关闭打开的光标。

你虽然commit了,但可能还有光标引用远程数据库吧,光标用完要close
再有,不必每次update都commit,可以在整个for循环结束之后,一次性commit。

具体解决办法有三:

--ALTER SESSION
alter sesssion close database link <dblink_name>;

--使用包
DBMS_SESSION.CLOSE_DATABASE_LINK(dblink_name);

--服务端sqlnet.ora配置,间隔清理非活动的session
SQLNET.EXPIRE_TIME= <inteval time>
coolkisses 2011-12-10
  • 打赏
  • 举报
回复
同意上面的方案
一种方案就是 update 一次,就开关一次session
另一种方案,全部update完毕后,一次性commit
wallace_jjh 2011-12-10
  • 打赏
  • 举报
回复
不好意思,这个“SmallTransHolder.trans.newTransExecute”是启动事务吗?
如果是开启事务,把他放到for外层试试。
gejigang2006 2011-12-10
  • 打赏
  • 举报
回复
for (int bathno = 0; bathno < no; bathno++) {
// 待接入数据
final List<?> bud = daoSupport.query(sqlstr);//也是一个从Dblink拿数据的select
try {
SmallTransHolder.trans.newTransExecute(new ISmallTransService() {
public void doExecute() throws Exception {
String sql = "update bud"+getDbLink(session)+" a set (download_status,download_date,back_remark,new_doing_id)"
+"=(select '2',sysdate,'OK',new_doing_id from bud_cache b where a.b_doing_id=b.b_doing_id) where exists (select 1 from bud_cache b where a.b_doing_id=b.b_doing_id)";
daoSupport.execute(sql);
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
logger.debug(e.getMessage(), e);
}

}
}大约是这些
[Quote=引用 3 楼 wallace_jjh 的回复:]
能否把代码发一下,我刚才试了试
for i in 1..1000 loop
insert into a@dblink values(..);
end loop

没有问题,都能提交上去啊
[/Quote]
wallace_jjh 2011-12-10
  • 打赏
  • 举报
回复
能否把代码发一下,我刚才试了试
for i in 1..1000 loop
insert into a@dblink values(..);
end loop

没有问题,都能提交上去啊

3,499

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧