3.3.3.4. 在 web Server 中执行数据库脚本
Web Server 执行数据库脚本的机制用于更新数据库,这个操作在应用程序服务启动、中间件块(block)初始化期间激活。显然,应用程序应该已经构建并部署在 Web Server 上,即在生产环境或开发人员的 Tomcat 实例中。
根据下面描述的条件,该机制执行创建或更新脚本,也就是它可以从头开始初始化 DB 并对其进行更新。但是,与上一节中描述的 Gradle createDb
任务不同,数据库必须存在才能初始化 - 在 Web Server 中不会自动创建 DB,而只是执行脚本。
Web Server 中执行脚本的机制如下:
-
应用程序从数据库脚本目录读取脚本,该目录由cuba.dbDir应用程序属性定义,该属性的默认设置为
WEB-INF/db
。 -
如果数据库没有
SEC_USER
表,则被视为空数据库,会使用创建脚本运行完整初始化过程。执行初始化脚本后,这些脚本的名称会存储在SYS_DB_CHANGELOG
表中。所有可用的更新脚本的名称也存储在同一个表中,但是并没有执行过这些更新脚本。 -
如果数据库有
SEC_USER
表,但没有SYS_DB_CHANGELOG
表(当在现有生产环境数据库上首次启动这里描述的机制时就会出现这种情况),这种情况下不执行任何脚本,而是创建SYS_DB_CHANGELOG
表,并存储所有当前可用的创建和更新脚本的名称。 -
如果数据库同时具有
SEC_USER
和SYS_DB_CHANGELOG
表,则执行先前未将名称存储在SYS_DB_CHANGELOG
表中的更新脚本,然后将这些脚本名称存储到SYS_DB_CHANGELOG
表中。脚本执行的顺序由两个因素决定:应用程序组件的优先级(参阅数据库脚本目录:10-cuba
、20-bpm
,…)和按字母顺序排序的脚本文件名称(参考update
目录的子目录)。在执行更新脚本之前,先检查是否已运行应用程序组件的所有创建脚本(通过检查
SYS_DB_CHANGELOG
表)。如果某个应用程序组件使用的数据库未初始化,则会执行其创建脚本。
通过cuba.automaticDatabaseUpdate应用程序属性启用在服务器启动时执行脚本的机制。
在运行中的应用程序中,可以使用 update
作为参数调用 app-core.cuba:type=PersistenceManager
JMX bean 的 updateDatabase()
方法来启动脚本执行机制。显然,这种方式只能更新现有的 DB,因为无法登录只有空 DB 的系统来运行 JMX bean 方法。请注意,如果部分在中间件启动或用户登录期间初始化数据模型与数据架构不匹配的话,会发生不可恢复的错误。这就是一般都在服务器启动时数据模型初始化前执行数据库自动更新的原因。
JMX app-core.cuba:type=PersistenceManager
bean 还有一个与 DB 更新机制相关的方法: findUpdateDatabaseScripts()
。它返回目录中可用的但未在 DB 中注册(尚未执行)新的更新脚本列表。
有关使用服务器数据库更新机制的建议,请参阅在生产环境中创建和更新数据库。