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

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

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


Java应用程序与Oracle数据库交互注意事项_第1张图片

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


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


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

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


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

Java应用程序与Oracle数据库交互注意事项_第2张图片

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

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

Java应用程序与Oracle数据库交互注意事项_第3张图片

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


你可能感兴趣的:(Java应用程序与Oracle数据库交互注意事项)