通过OCP考试

二十天没有写新日志,真对不起关心这个blog的朋友们。

从四月份开始准备了三个月,这些天参加了Oracle 9i的培训,并顺利通过了OCP全部四门课的考试。虽然证书还要一个多月才能拿到,但总算可以暂时把心放下了。目前的工作和Oracle没有直接关系,考这个一是为拿证书(以前从没考过认证),证明自己的学习能力;二是强迫自己对数据库产品进行比较全面的了解。

Oracle大学的高老师很有经验,十分感谢他,让我们在了解知识点的同时还掌握了不少对实际出现情况的应对方法,同时也感受到考过OCP绝不代表你可以处理全部问题了,没有一两年的实际经验,对于生产数据库还是少碰为妙,这和背背书应付考试完全两个概念。

虽说培训环境还不错,可每天来回路上挤三个多小时的车,我还是快坚持不住了。这周体检出血液中某种细胞低于正常值,医生说是累的,联想到程序员王俊,以及再早些我校青年教师的突然去世,深切体会到“身体是革命的本钱”所言极是,同志们都要注意那!

这个月开始又要和自己喜欢的Eclipse打交道了(Eclipse 3.1正式版已经发布),我一有时间还是会在这里写下所学的心得体会,常来看看哦。

管理Oracle数据库要注意的一些问题

以下针对Oracle9i数据库:

  1. Commit操作不强制将database buffer内容写到文件;Commit操作后,server process在提示用户“操作已完成”之后才释放相关资源的锁;
  2. 创建数据库时,数据文件和日志文件必须用size指定大小,或用reuse指定到某个已有文件,否则命令会失败;
  3. 若丢失了所有control file的副本,可以通过重建control file恢复数据库;
  4. 在创建unique或primary key约束时,Oracle自动创建索引(名称同约束名),删除这个索引前必须先删除对应约束;
  5. Partitioned table可以被多个进程同时查询或操作;
  6. 当前的log sequence number被存放在control file和每个data file的头部(由CKPT进程写入),log group里的每个member具有同样的log sequence number;
  7. 通过DBA_OBJECTS表可以找到哪些对象存在错误,例如视图所依赖的表已被删除,这个视图的status会被标为invalide;
  8. Read-Only的表空间里的对象可以被Drop,因为该操作只影响dictionary;
  9. 当使用external验证方式时,不能指定password expire;
  10. DBA是role,而不是privilege(SYSDBA和SYSOPER是privilege);
  11. 使用truncate table命令后,并非所有extents都被释放,table将保留个数为minextents的extents;
  12. SMON后台进程负责数据库的recovery,以及合并碎片;
  13. 查询USER_XXX和dictionary表不需要具有select any table权限;
  14. 对于标志为unused的列,可以在同一张表中创建与它同名的列;
  15. Undo段在刚创建时是offline状态的;
  16. 用户自己唯一可以使用alter user命令修改的属性是identified by;
  17. 要修改tablespace的数据文件为自动扩展,应该使用alter database而不是alter tablespace命令;
  18. 创建用户和创建表的动作不记录在alertSID.log文件里;
  19. 没有”Create Index”权限,因为”Create Table”包含了它,Alter和Drop也一样;
  20. 具有”Create Any XXX”权限的用户在其他用户下创建的对象,其所有者是那个用户;
  21. Unlimited tablespace系统权限,只能直接授给用户,而不能授给角色;
  22. Externally管理的角色不能设置为default role;
  23. 没有”Truncate Table”权限,用户拥有”Drop Table”权限即可执行Truncate操作;
  24. Create SPFILE From PFILE命令可以反过来用,即Create PFILE From SPFILE,若不指定PFILE/SPFILE的名称则使用缺省名称;
  25. TableSpace的Storage选项里的Initial和Next值应为Minimum Extent值的整数倍,否则创建语句会失败;
  26. LogSwitch事件会记录在alert_log文件里;
  27. Oracle缺省使用AL16UTF16作为National Character Set,Database Character Set用于SQL和PL/SQL代码,National Character Set用于NChar、NVarchar2和NClob字段;Database Character Set不能使用固定长度多字节类型字符集;
  28. 对于Rollback Segment: minextents至少为2(推荐20),pctincrease永远为零,可以是public或private但一旦确定就不能更改,optimal参数至少为该segment的initial size,initial和next最好相等已保证每个extent具有相同的大小,maxextents最好不要设置为unlimited;刚创建时的roolback segment是offline状态的,必须手工设置为online才可用;drop前必须先设置为offline;
  29. 对于Temporary Tablespace和Temporary Segment: UNIFORM SIZE值最好是SORT_AREA_SIZE的整数倍;Tempfiles不能改名,不能只读,不会进行recovery处理,不能用alter database命令创建,总是nologging模式;
  30. 字典区管理的表空间可以指定自定义的storage选项;本地区管理的表空间的storage选项不可更改,可以指定为自动段空间管理;
  31. 待续。

Hibernate用Mysql数据库时链接关闭异常的解决

在一个项目中,客户要求除操作系统外全部使用免费软件,因此我使用了Mysql 4.0作为数据库服务器,其JDBC驱动为3.0.9版本,在给客户安装后调试一切正常。可是到了第二天,只要一登录就提示“No operations allowed after connection closed”异常,显示在浏览器上。在经过一番检查后我发现,在这种情况下只要重新启动Tomcat就恢复正常,然而到了第二天问题依旧。

在网上查找一下,原来Mysql在经过8小时不使用后会自动关闭已打开的连接,摘录原文如下:

5.4. I have a servlet/application that works fine for a day, and then stops working overnight
MySQL closes connections after 8 hours of inactivity. You either need to use a connection pool that handles stale connections or use the “autoReconnect” parameter (see “Developing Applications with MySQL Connector/J”).

Also, you should be catching SQLExceptions in your application and dealing with them, rather than propagating them all the way until your application exits, this is just good programming practice. MySQL Connector/J will set the SQLState (see java.sql.SQLException.getSQLState() in your APIDOCS) to “08S01” when it encounters network-connectivity issues during the processing of a query. Your application code should then attempt to re-connect to MySQL at this point.

在客户那边,晚上时间是不会有人使用这个系统的,就造成了系统中原先没有考虑到的这个情况。

为此我试验了三种方法:1、在数据库的url中加入autoReconnect=true;2、在每次调用getSession()方法时判断session.isClosed()是否为真,若为真则调用session.reconnect();3、在经过两天,事实证明前两种方法都不起作用的情况下,我在这个页面找到了第三种方法,即不使用Hibernate内置的连接池(Hibernate强烈推荐不使用但我以前一直在用),改用C3P0连接池,这个连接池会自动处理数据库连接被关闭的情况。要使用C3P0很简单,先从Hibernate里把c3p0-0.8.3.jar复制到项目的lib目录中,再在hibernate.properties里去掉hibernate.c3p0开头的那些属性的注释(使用缺省值或自己需要的数值),这样Hibernate就会自动使用C3P0代替内置的连接池了。到目前为止前面的问题没有再出现过。

以前对Hibernate警告不要使用内置连接池作产品用途没有太放在心上,这次是一个教训,所以不论从稳定还是性能的考虑,都应该选择相对更加成熟的连接池。

update:除了连接池的原因,原先写的HibernateDAO类也有问题,在有些情况下一个session会被多个请求反复使用,现在已改正。另外,c3p0这个名字不是星球大战里那个机器人么?