检查H2数据库是否已损坏,并创建新的(如果损坏)



我是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上下文中。在我发现没有机会检查数据库是否损坏并删除数据库之前。

最新更新