一些数据库和 transaction 的实现

前面提到 JDBC 在 spring 中应用重要的是提供一个 driver,我们这里列举一些常用的数据库的相关信息:

  • H2,我们可以使用 org.h2.jdbcx.JdbcDataSource(支持 in-memory)
  • HSQLDB,可以用 org.hsqldb.jdbc.JDBCDriver(支持 in-memory)
  • MySQL,我们可以使用 com.mysql.jdbc.Driver
  • Oracle,我们可以使用 oracle.jdbc.driver.OracleDriver
  • sqlite,我们可以使用 org.sqlite.JDBC,连接的 URL 一般写为 jdbc:sqlite:file.db(支持 in-memory)

JDBC 的核心作用就是提供了一个中间层,需要访问数据库的程序员可以避免直接与不同类型的数据库打交道,而只在 JDBC 提供的 API 上工作,后面的细节完全交由以上 driver 实现。可能更早的实现是 Microsoft 的 ODBC,这是一个 C 的实现,现在可以找到一些类似的开源实现,如 iODBCunixODBC。对于 C++ 的实现似乎没找到一个比较统一的一致的看法,像 wxWidget 或者 Qt 都提供了自己的模块来管理数据库,前面提到的 CppCMS 也有一个自己的数据库模块这个不知道是不是想进入 boost,另外还有 SQLAPI++SOCI

直接使用 JDBC 一般需要 import 这两个 package,java.sql javax.sql。使用过程一般是载入 driver(老的需要手工 load 对应的 driver class,现在据说不用了),然后从 DriverManager 调用 getConnection 获得到数据库的连接(这个地方也有使用 connection pool 来做的,常见的有 C3P0),这个 Connection 对象可以生成 Statement 或者 PreparedStatement,通过这些对象的 execute 我们完成与数据库的交互(提交 SQL 获得返回的结果)。整个环节里面一旦有问题一般都是抛出 SQLException,这就是 Spring 的 template 简化的地方,通过 JdbcTemplate(处理的 query 里面使用 ? 占位)或者 NamedJdbcTemplate(处理的 query 里面使用 :xxx 类型的占位),对应的三类命令,DDL(data definition language,主要对应创建表格,删除表格之类)、DML(data manipulation language,主要对应 select、insert、update、delete) 和 DCL(data control language,主要是 grant 之类权限的设定) 使用 execute(DCL 和 DDL)、update(DML 除了 select 以外的)/query(DML 中的 select)三种方法提交。

对于 JPA 这个东西只是一套 interface(它提供的接口、异常以及相关的东西可以在这个文档里面找到),我们需要 ejb3-persistence.jar 里面的 javax.persistence,实现 JPA 的有不少,比如前面说的 hibernate 也是 JPA 的实现者,当然 JPA 本身的设计也受到了这些 ORM 框架的影响。hibernate 中通过 annotation 来标注 POJO 与 DB 中表的关系的方式是符合 JPA 标准的。提供的 entity manager 也是实现了 JPA。在 Spring 中使用 JPA 可以使用 LocalEntityManagerFactoryBean(application managed),通过这个 factory 我们就能获得对应的 entity manager(比如 hibernate 提供的),这时我们需要提供一个独立的 xml 用来描述 persistent unit(包括如何访问数据库)。另外还有一套 container managed,这时我们和 JDBC 使用相似,需要在 spring 中提供 data source,并选择一个 jpa vendor adaptor 将如 hibernate 的 JPA 实现传入 LocalContainerEntityManagerFactoryBean。实现对应的 DAO 与 JDBC 不大一样的是,我们不再嵌入一个 JDBC template 到 DAO 中,而嵌入一个 entity manager,我们直接调用这个 entity manager 的方法就能完成大部分工作了(这个部分其实和 django 的 model 提供的功能是一致的)。

transaction 的实现

某些特殊的情况我们需要 transaction,这在前面两篇 blog 中(关于 spring关于 SQL)已经稍微有些提及,但是比较好奇的是如何实现一个database transaction 呢。wiki 上有列出来下面两种策略

  • 一种策略是 write-ahead logging,在所有的操作之前先写 log,log 往往包含 undo 和 redo 的操作方式,这样一旦出现问题可以从 log 开始分析,进行必要的 rollback 或者别的什么。常见的算法是 ARIES
  • 一种是 shadow paging,它利用了 copy-on-write 的技术,要写入时先 copy 到单独的 page 上,确认完成后,将含有这个的指向全部更新到新的 page 上,但是这样一来有时候更新会耗时很多。

以上策略都需要 locking,但是某些特殊情况(某些 key/value store?),我们可以通过 versioning 来避免 不必要的锁。

——————
And before I had done speaking in my heart, behold, Rebekah came forth with her pitcher on her shoulder; and she went down to the well, and drew water: and I said to her, Let me drink, I pray you.

Advertisements
一些数据库和 transaction 的实现

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s