一.Java与元数据
元数据是关于数据的数据(data about data)。在编程语言上下文中,元数据是添加到程序元素如方法、字段、类和包上的额外信息。
元数据的作用:
1. 一般来说,元数据可以用于创建文档,跟踪代码中的依赖性,执行编译时检查,代码分析。
2.元数据还可用于协助程序元素与框架或者EJB、EMF 和 TestNG这样的工具之间的通信。EJB 3.0就广泛地应用了Java元数据,通过元数据来实现声明性请求企业服务,依赖性以及资源注入,消除了严格的EJB组件模型约束,并且取代了复杂的XML配置文件。
3.元数据甚至使我们可以不用修改核心语言,就能够在 Java 语言中添加新功能,使核心语言成为一种开放式语言。在纯面向对象的语言中实现AOP就是使用元数据进行语言扩展的一个很好例子。AspectWerkz、JBoss AOP以及AspectJ5 使用元数据将类的语义转换为一个aspect、将数据字段转换为一个pointcut、将方法转换为一个advice,等等。
Java平台的元数据
Java 元数据(Annotation)是 J2SE 5.0 (研发历时近三年,于2004年9月30日正式发布,代号为“Tiger”)新增加的功能之一,它在JSR-175规范中有详细定义。该机制允许在 Java 代码中添加自定义注释,并允许通过反射(reflection),以编程方式访问元数据注释。通过提供为程序元素附加额外数据的标准方法,元数据功能具有简化和改进许多应用程序开发领域的潜在能力,其中包括配置管理、框架实现和代码生成。
Annotation不直接影响程序的语义。然而,开发和部署工具可以读取这些注释,并以某种形式处理这些注释,可能生成其他 Java源程序、XML配置文件或者要与包含注释的程序一起使用的其他组件,从而影响运行状态的程序的语义。注释可以从源代码中读取,从编译后的.class文件中读取,也可以通过反射机制在运行时读取。
Annotation具有以下的一些特点:
1.元数据以标签的形式存在于Java代码中。
2.元数据描述的信息是类型安全的,即元数据内部的字段都是有明确类型的。
3.元数据需要编译器之外的工具额外的处理用来生成其它的程序部件。
4.元数据可以只存在于Java源代码级别,也可以存在于编译之后的Class文件内部。
事实上,早在JDK5.0推出语言级的元数据机制Annotation以前,就一直存在对元数据的需求。但是由于没有提供表达元数据的标准机制,出现了各种解决方案。下面罗列了一些例子
l transient 关键字
l Serializable 标记接口
l xml 部署描述文件
l manifest.mf 文件
l Javadoc 标记(将文档直接写在源程序里,极大的方便了文档的编写)
l XDoclet(使用类似于JavaDoc的语法撰写描述信息,并使用工具生成描述文件)
这些方法都存在一定的局限性,比如使用关键字不具有扩展性,用户自定义新的关键字;标记接口没有提供额外的信息,它们不能带有参数,并且只能处理类,而不能处理字段或方法或包。Javadoc和XDoclet标记不会被编译器检查。
最后,我们再详细的对比一下Annotation和XML部署描述文件的优劣
1.XML配置文件与代码文件分离,不利于一致性维护,缺乏在运行时的反射机制。而Annotation与代码一起被编译器处理,并能够在运行时访问。
2.通常XML配置文件都很复杂而且冗长,为了配置代码,XML文件必须复制许多信息:比如代码中类名字和方法名字。Java注释则不同,它是代码的一部分,不需要额外的引用就可以指明配置信息。
3.XML配置文件是文本文件,没有显式的类型支持,需要到运行时刻才能发现隐藏的错误。而Annotation是类型安全的,它会被编译器检查。
4.XML文件可以表达复杂的关系,但是在注释中我们却很难表达复杂的或层次的结构。
5. XML配置文件是在代码之外被单独处理的,也就是说基于XML的配置信息不是硬编码的,可以部署的时候进行修改。而修改Annotation则需要进行重新编译,不过我们可以利用AOP提供的机制为已有的代码添加Annotation。通过部署不同的AOP模块,就能使代码具有不同的Annotation,但比起直接修改XML显得复杂。
总而言之,注释是简单易用的,并且对大多数应用来说已经足够了。而XML文件更复杂,但具有部署的灵活性,因而被用来处理与部署相关的决策。注释与XML配置文件可以一起使用。由于注释只能保存相当少的配置信息,只有预先集成的框架组件(类似在框架组件中已经完成了大多数预备工作)可以广泛地把注释作为配置选项。而XML配置文件作为一个可选的重载机制,可以用于改变注释的默认行为。
二.基于元数据的Spring事务声明
什么是脏读、不可重复读、幻读
1.脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
2.不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果只有在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题。
3. 幻读:是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主复本时,发现作者已将未编辑的新材料添加到该文档中。如果在编辑人员和生产部门完成对原始文档的处理之前,任何人都不能将新材料添加到文档中,则可以避免该问题。
补充:基于元数据的Spring声明性事务:
Isolation属性一共支持五种事务设置,具体介绍如下:
l DEFAULT 使用数据库设置的隔离级别(默认) ,由DBA默认的设置来决定隔离级别.
l READ_UNCOMMITTED 会出现脏读、不可重复读、幻读(隔离级别最低,并发性能高)
l READ_COMMITTED 会出现不可重复读、幻读问题(锁定正在读取的行)
l REPEATABLE_READ 会出幻读(锁定所读取的所有行)
l SERIALIZABLE 保证所有的情况不会发生(锁表)
不可重复读的重点是修改: 同样的条件, 你读取过的数据, 再次读取出来发现值不一样了 幻读的重点在于新增或者删除 同样的条件, 第1次和第2次读出来的记录数不一样