IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

Java的那些事儿

OS与Oracle 2013-05-29 22:17:54 累计浏览 3,878 次
本机暂存

   Java于我,是一门很实用的语言。在大学里,起码在我们那时的大学,Java可不是一门登堂入室的语言,那是汇编语言,C语言,甚至Pascal语言的天下。不过Java却是学生时代兼职的第一语言(嘿嘿,真实用)。这对大学的语言教学真有那么一点讽刺意味。

   当然,我觉得相比C/C++,Java做为后起之秀,吸取着以前语言的经验教训,而又没有类似C++必须兼容C的沉重负担,一切从新设计,这使它变成了一门简单而又强大的语言。还有,Java有着丰富的入门教程,新手很容易通过例子掌握一个具体的知识点。Java的IDE应该是做得比较出色的,如JBuilder,JDeveloper,Eclipse。

   而正式工作后,在实际项目中使用C/C++的机会其实也很少,这是一个开发效率的问题,虽说C/C++的运行效率比Java更高,但现在人们更关注的,却是开发效率,还有应用总体的高性能与高可扩展性问题。对于开发并发应用,Java提供了内置的支持,而C/C++,线程安全,并发技术,对于一般的入门者那应该是很高阶的话题吧。

   当然,Java的易于上手,并不表明新手们就能把它用得很好。例如,对于与数据库打交道,没有对数据库的基础知识那也是不行的,对于Java来说,很大一部分就在于如何使用JDBC开发出高性能的数据库Java应用程序。这里当然可以推而广之,对于其它的编程语言,这一问题也广泛存在,如如何使用OCI开发高性能的数据库C应用程序,Pro*C应用程序,PHP应用程序。

   对于Oracle数据库而言,起码有以下几点是Java程序员所应该掌握的:

   第一是连接池技术,数据库默认就提供了对高并发的支持。应用程序有两种极端,一种是全局只使用一个连接,这很幼稚,但这确实存在;另一种是只要需要操作数据库,就创建一个新的连接,从而会出现同一时刻,并发数据库连接数成千上万的情形。解决以上两种问题的方法就是使用连接池技术,并设置一个合理的连接数的最大值,这取决于数据库服务器的CPU个数,最佳的连接数一般应该在CPU个数的2到4倍左右。

   UCP是Oracle提供的连接池驱动,以ucp.jar的形式提供。一个简单的示例如下:

PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
pds.setURL("jdbc:oracle:thin:@//localhost:1521/orcl");
pds.setUser("scott");
pds.setPassword("tiger");
pds.setInitialPoolSize(20);
pds.setMinPoolSize(20);
pds.setMaxPoolSize(20);
Connection conn = pds.getConnection();

   如果不用连接池,就不需要上面的ucp.jar,只需要一般的驱动,如ojdbc5.jar。

OracleDataSource ds = new OracleDataSource();
ds.setURL("jdbc:oracle:oci:@//localhost:1521/orcl");
ds.setUser("scott");
ds.setPassword("tiger");
Connection conn = pds.getConnection();

   第二是语句池技术,解析SQL语句并生成执行计划,对于数据库引擎来说是很昂贵的操作。因此,在SQL语句中必须使用绑定变量而不是文本常量。另一方面,即使通过绑定变量避免了重新生成执行计划,但如果还存在软解析也会给系统带来额外的CPU消耗。如下面的语句:

while(true){
 OraclePreparedStatement stmt = (OraclePreparedStatement) conn.prepareStatement("select ename from emp where empno = ?");
 stmt.setString(1, "xxx");
OracleResultSet rs = (OracleResultSet) a_stmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getString(1));
}
}

   每执行一次conn.prepareStatement都会导致数据库里的一次软解析。解决方法有三种:

   1. 把这个conn.prepareStatement移动while循环的外面。

   2. 对于直接从DataSource获取的连接,启用连接的语句缓冲。

conn.setImplicitCachingEnabled(true);
conn.setStatementCacheSize(10);

   3. 而对于UCP连接池,则可以通过设置连接池的属性启用语句的缓冲。

pds.setMaxStatements(10);

   第三是各种泄露问题,连接泄露,语句游标泄露,锁泄露。Java语言只会帮助回收应用程序里的内存结构,却不会帮助你关闭曾经打开的数据库连接、游标,以及对事务的提交或回滚。下图是一个演示锁泄露的例子,粉红色区域面积越来越大,代表等待事件enq: TX - row lock contention越来越严重。一个常见的原因就是异常处理的代码中忘了对事务进行commit或者rolloback。

   原图已失效

同分类推荐文章

  1. 使用deepseek进行Oracle恢复,引起重大故障 (2026-06-22 10:56:00)
  2. 接手一个只差临门一脚的数据库恢复 (2026-06-18 00:13:09)
  3. 我做了一个 AI 版的 StarRocks 升级风险扫描工具,直接帮我定位到一个风险 (2026-06-15 01:00:00)

查看更多 数据库 文章 →

建议继续学习

  1. SmartSprites - 命令行形式的CSS Sprites生成器 (累计阅读 123,894)
  2. Java开发岗位面试题归类汇总 (累计阅读 22,156)
  3. android 开发入门 (累计阅读 19,527)
  4. 我的PHP,Python和Ruby之路 (累计阅读 13,147)
  5. HashMap解决hash冲突的方法 (累计阅读 12,654)
  6. Facebook 网站架构 (累计阅读 11,112)
  7. 一个大二学生有关如何成为一名软件工程师的疑问及答复 (累计阅读 9,181)
  8. 腾讯php程序员面试题目答案 (累计阅读 8,974)
  9. Java程序员应该知道的10个eclipse调试技巧 (累计阅读 8,012)
  10. 如何让员工忠于公司? (累计阅读 7,940)