我是C#开发人员,需要维护使用Spring Boot Framework开发的现有Java服务应用程序。负责的开发人员不久前离开了公司,因此我没有可能获得帮助...到目前为止
我需要实现的目标:
- 检查是否使用过的H2数据库已损坏
- 如果损坏:删除数据库并创建一个新的空数据库
我想我需要在主入口处实施检查和娱乐
public static void main(String[] args) {
SpringApplication.run(MessageServiceApplication.class, args);
}
我知道,如果数据库不存在,则在启动时会在启动时自动创建DB。到目前为止,一切都很好。现在,我需要检查数据库是否已损坏。我考虑过在数据库上执行查询,如果得到例外,我会重新创建数据库。
数据库是H2文件数据库。
希望我能得到一些帮助。
编辑#1 我考虑过实现在启动时被调用的Utils类:
public class H2DbUtils {
public boolean IsH2FileDatabaseCorrupted()
{
boolean isCorrupted = false;
// Implement Logic to determine if db is corrupted
return isCorrupted;
}
public boolean ReCreateH2DatabaseFile()
{
boolean reCreated = false;
// Implement Logic to recreate db
return reCreated;
}
}
在启动
上打电话 public static void main(String[] args) {
H2DbUtils h2DbUtils = new H2DbUtils();
if(h2DbUtils.IsH2FileDatabaseCorrupted()) {
h2DbUtils.ReCreateH2DatabaseFile();
}
SpringApplication.run(MessageServiceApplication.class, args);
}
更新2018-03-20
目前找到了以下解决方案来实现这一目标:
@Configuration
@Component
public class DataSourceBean {
@Autowired
private Environment currentEnvironment;
private final Logger logInstance = LoggerFactory.getLogger(this.getClass());
@Bean
@Primary
public DataSource dataSource()
{
DataSource dataSource = null;
try
{
// We try to get the Meta Data out of the database.
// If this fails the database is corrupted or has an other problem
// All in all this means we need to delete the current database file
// to avoid further problems.
dataSource = this.getDataSource();
dataSource.getConnection().getMetaData();
return dataSource;
}
catch (Exception ex)
{
logInstance.error("The h2 database file '{}' seems to be corrupted! Error: {}",
currentEnvironment.getProperty("dataBaseFile"),
ex.getMessage());
// dataBaseFile=./db/mydatabase.db
String databaseFilePath = String.format("%s.%s", currentEnvironment.getProperty("dataBaseFile"), "h2.db");
databaseFilePath = databaseFilePath.replace("/", "\");
File databaseFile = new File(databaseFilePath);
if (databaseFile.exists()) {
File parentDirectory = new File(databaseFile.getParent());
if (parentDirectory.isDirectory()) {
try {
FileUtils.deleteDirectory(parentDirectory);
} catch (Exception fex) {
logInstance.error("Error occurred deleting the folder {}. Error: {}",
parentDirectory.getAbsolutePath(),
fex.getMessage());
}
}
}
dataSource = this.getDataSource();
}
finally {
return dataSource;
}
}
@ConfigurationProperties(prefix = "spring.datasource")
private DataSource getDataSource() {
return DataSourceBuilder.create()
.url(currentEnvironment.getProperty("spring.datasource.url"))
.driverClassName(currentEnvironment.getProperty("spring.datasource.driverClassName"))
.username(currentEnvironment.getProperty("spring.datasource.username"))
.password(currentEnvironment.getProperty("spring.datasource.password"))
.build();
}
可以覆盖数据源bean并检查数据库文件
@Bean
@Primary // this will override the datasource autoconfiguration and use your own everywhere
public DataSource dataSource() {
// Open Connection
// Check Database
// Close Connection
// IF File corrupted delete files
// create regular data source
}
我尝试将几个侦听器添加到Spring Boot应用程序中,例如:
SpringApplication springApplication = new SpringApplication(testApplication.class);
springApplication.addListeners(new FailedEvent(testApplication.class));
SpringApplication.run(testApplication.class, args);
,但我从来没有在春季应用程序的创业公司中找到其中一位听众。由于springapplication.lun似乎可以启动整个弹簧上下文,因此当应用程序在springapplication中停止时,也无法注入或获取配置环境以获取连接字符串。
我假设春天尝试进行初始化的冬眠等,依此类推,并且由于DB被损坏而无法创建数据库连接
org.h2.jdbc.JdbcSQLException: Allgemeiner Fehler: "java.lang.RuntimeException: rowcount remaining=2 SYS"
General error: "java.lang.RuntimeException: rowcount remaining=2 SYS" [50000-196]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) ~[h2-1.4.196.jar:1.4.196]
at org.h2.message.DbException.get(DbException.java:168) ~[h2-1.4.196.jar:1.4.196]
at org.h2.message.DbException.convert(DbException.java:295) ~[h2-1.4.196.jar:1.4.196]
at org.h2.engine.Database.openDatabase(Database.java:307) ~[h2-1.4.196.jar:1.4.196]
at org.h2.engine.Database.<init>(Database.java:270) ~[h2-1.4.196.jar:1.4.196]
at org.h2.engine.Engine.openSession(Engine.java:64) ~[h2-1.4.196.jar:1.4.196]
at org.h2.engine.Engine.openSession(Engine.java:176) ~[h2-1.4.196.jar:1.4.196]
at org.h2.engine.Engine.createSessionAndValidate(Engine.java:154) ~[h2-1.4.196.jar:1.4.196]
at org.h2.engine.Engine.createSession(Engine.java:137) ~[h2-1.4.196.jar:1.4.196]
at org.h2.engine.Engine.createSession(Engine.java:27) ~[h2-1.4.196.jar:1.4.196]
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:354) ~[h2-1.4.196.jar:1.4.196]
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:116) ~[h2-1.4.196.jar:1.4.196]
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:100) ~[h2-1.4.196.jar:1.4.196]
at org.h2.Driver.connect(Driver.java:69) ~[h2-1.4.196.jar:1.4.196]
这发生在springapplicatio.run上下文中。在我发现没有机会检查数据库是否损坏并删除数据库之前。