Java应用程序与Oracle数据库交互注意事项

最近在做的一个项目需要使用多线程Java应用程序与服务器上的Oracle数据库频繁进行数据交互。开发完成后,我们重新进行了多次安全性检查,具体项目如下:

1、在多线程调用,特别是循环调用时,实例化的preparedStatement变量必须在使用后或下一次实例化之前进行关闭操作,必要时还需要将该变量置空,帮助JVM进行垃圾回收。



如果不及时对使用过的资源进行关闭和回收,ps与数据库建立的连接不会自动得到释放,导致程序报错:ORA-01000: maximum open cursors exceeded 或者干脆不报错,返回空的查询结果等等。


2、与及时关闭ps的原理类似,线程中对数据库进行的UPDATE,INSERT和DELETE等操作必须及时commit。由于Oracle数据库在commit时会将同一张表的非查询访问串行化,不及时commit可能导致锁表等严重后果。这里出现的锁表在日志上显示的十分尴尬,一般为彻底卡死,不报错,不执行finally代码段,也看不到任何后续输出。


然而,过分迅速的commit往往也不是好事,当一个线程中的其他程序出错时,数据库操作的回滚显得十分必要。它在一定程度上避免了错误的数据库交互,增加了代码逻辑的鲁棒性。一般来说,可以使用下列操作:

首先,获取一个数据库连接,保存该连接之前的isAutoCommit属性,将当前的autoCommit属性设置为false。当确定线程中所有代码依预定逻辑正确执行时,commit该连接,并将其isAutoCommit属性恢复到之前的状态。


3、当多个线程同时对多张表进行操作时,可能出现互锁的问题。例如:


假设线程1和线程2都在本线程结束时才进行commit操作,当线程1在表B中插入数据时,表B暂时被锁,不允许其他线程进行非查询操作。同一时间,线程2在表C中插入数据,表C暂时被锁,不允许其他线程进行非查询操作。接下来,如果线程1想要更新表C中的数据,就会进入排队等待的状态,同样,线程2也无法对表B进行数据更新,导致两个线程互锁。

该问题的解决方案之一是将两个线程对各张表操作的顺序整理一致,例如:


这样就可以避免发生上述互锁情况了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值