首页 > Linux操作系统 > Linux操作系统 > 从一次故障解决想到的
近日进行开发环境例行检查,发现数据库中某张表多出一个字段。字段命名为过去一个已经被改名的字段名称,类型为number(9,2)(原来的类型为number(13)),没有comments信息。笔者心想:看来又有开发人员打开了JPA自动同步数据库开关了。
ORM框架技术是目前解决关系数据库模型和实体对象模型阻抗不一致的主流手段。通过配置文件或者配置标签,实现将实体类与关系数据表的映射。在应用代码中,只需要进行实体类型的操作,ORM框架会自动生成SQL语句,进行数据的持久化操作。
目前,业界流行的ORM框架有很多。最常见的可能就是Hibernate和ibatis,此外还有EJB3的持久性解决方案JPA。笔者遇到的开发系统就是建立在JPA解决方案下。
在一些框架中,提供了自动ddl的功能。也就是说,在应用启动的时候,会自动检查当前的实体对象映射关系是否和数据库表结构匹配。如果不匹配的话,会自动的生成ddl语句,并且在数据库上执行,同步数据库结构。很多应用中,这个开关是默认开启的。在笔者开发的系统中,是不允许使用这个功能的。
笔者遇到的问题就在于此。字段更名的变更已经很长时间,并且反复强调过自动同步开关的关闭。再次出现ddl同步的原因只有出现开发人员使用了非最新的代码实体类型,并且开启了自动同步功能开关。
不管如何,先把这个开发人员定位出再说吧。只能通过all_objects视图的last_ddl_time确定出大致的同步时间,尝试从Redo Log中获取对应的信息。在这个过程中,使用了logminer尝试获取到执行ddl操作时保留的会话信息。
SQL> alter system switch logfile;
System altered
SQL> select name from v$archived_log where first_time
NAME
---------------------
NBSDEVSTY
/nbsarch/NBSDEV/1_437_729298248.arc
SQL> select name from v$archived_log where first_time
NAME
--------------------
NBSDEVSTY
/nbsarch/NBSDEV/1_437_729298248.arc
SQL> exec dbms_logmnr.add_logfile('/nbsarch/NBSDEV/1_437_729298248.arc',dbms_logmnr.NEW);
PL/SQL procedure successfully completed
SQL> exec dbms_logmnr.start_logmnr(Options => dbms_logmnr.DICT_FROM_ONLINE_CATALOG);
PL/SQL procedure successfully completed
结果是令人沮丧的,分析日志的结果虽然可以找到执行的ddl语句。但是由于用户登录是使用前端JDBC进行连接,所以Session_Info信息返回的都是UNKNOWN。
SQL> select scn,session_info, timestamp,sql_redo from v$logmnr_contents where sql_redo like '%STK_STOCKHISTORY%';
SCN SESSION_INFO TIMESTAMP SQL_REDO
----------------------------------------------------------------------
96907227 UNKNOWN 2011/2/14 15:53:02 analyze table NBS.STK_STOCKHISTORY
estimate statistics;
96907255 UNKNOWN 2011/2/14 15:53:02
alter table STK_STOCKHISTORY
add REASON_SEQ number(19,2);
96907265 UNKNOWN 2011/2/14 15:53:02
alter table STK_STOCKHISTORY
add SERIESCODE_SEQ number(19,2);
在没有其他更好办法的情况下,最后笔者只能使用笨办法:依次找每个开发人员环境进行确认。最后还是定位到了一位开发人员身上,发现的确是使用的非配置管理的旧代码,并且开启着自动同步开关。故障解除…
虽然这个问题没有使用什么高明的技术进行解决,最后等于也是用笨办法搞定。但是思考下,还有有些想法。
关于ORM自动同步功能
首先,笔者承认ORM自动同步功能是一个非常有意义的功能。很长时间里,我们的开发设计人员精力都是集中数据库ER关系上。而我们进行的面向对象分析设计,关注的重点是在类的职责划分以及类之间的交互上。过多的关注数据库会造成这种脱节逐步深化。设计实体类,之后使用ORM自动同步生成数据库结构,也就自动的消除了这种现有数据表后又实体类的情况。
但是,目前的ORM自动同步,还存在一些缺陷和不足。数据库设计绝不仅仅是数据表和列表为代表的逻辑设计。在一些中大型系统中,物理设计、SCHEMA选择尤为重要。这不仅仅是关系开发规范的落实,而且关系到系统未来性能合理性等。
有的朋友可能会提出先创建表,之后由数据库规划人员整理结构。这样做的成本其实是更高的,因为没有一个统一的DB设计思路。而且在遇到发起变更的时候,前后不一致的问题会很大。
第三,ORM自动同步还存在一些需要逐步完善的内容。注释、主键、索引等数据库特定的对象,还是鲜有自动生成支持。后补完善的工作量也是很巨大的。
最后,自动ORM同步时需要专门的工具进行支持。一个简单的道理,如果我们在本地添加一个试验性的字段,自动同步在开发环境下,相当于把未确认的代码迁入。这样是一种绝对不允许的行为!所以,通常使用这种方法的团队,都是使用本地小型数据库进行支持,如SQLite。在确认代码结构后,将ddl脚本和实体类脚本一起同步到配置管理和开发环境下。
结论:采用一项技术,特别是开发流程技术,要进行综合的考量才能确定。主要是人力、制度规范、支持工具和项目性质几个因素确定。一定的开发团队水平,适合合理的制度,支持技术的工具软件以及具体项目属性,才能采用最适当的技术策略。技术方案没有好坏,只有是否适当。
个人观点,仅供指正。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/17203031/viewspace-687374/ ,如需转载,请注明出处,否则将追究法律责任。