【问题标题】:Tomcat Error: Embedded H2 DB Read-OnlyTomcat 错误:嵌入式 H2 DB 只读
【发布时间】:2018-04-01 05:46:36
【问题描述】:

尝试启动使用 embedded h2.db 文件的应用程序时,我的 tomcat 日志中出现以下错误:

Caused by: org.h2.jdbc.JdbcSQLException: The database is read only**; SQL statement:<br>
UPDATE DATABASECHANGELOGLOCK SET LOCKED = TRUE, LOCKEDBY = '192.168.122.1 (192.168.122.1)', LOCKGRANTED = '2017-10-19 17:06:08.499' WHERE ID = 1 AND LOCKED = FALSE [90097-175]<br>
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:332)
        at org.h2.message.DbException.get(DbException.java:172)
        at org.h2.message.DbException.get(DbException.java:149)
        at org.h2.message.DbException.get(DbException.java:138)
        at org.h2.engine.Database.checkWritingAllowed(Database.java:1784)
        at org.h2.table.Table.checkWritingAllowed(Table.java:1082)
        at org.h2.engine.User.hasRight(User.java:114)
        at org.h2.engine.User.checkRight(User.java:100)
        at org.h2.command.dml.Update.update(Update.java:87)

如您所见,它无法运行更新语句来锁定数据库。

解决问题:
1.我打开一个h2 shell运行并直接连接到h2 db:

sudo java -cp h2.jar org.h2.tools.Shell -url "jdbc:h2:file:/usr/share/tomcat/ellucianmobile/banner-mobileserver/banner-mobileserver-prodD" -driver "org.h2.Driver" -user "sa" -password "" 
  1. 然后我列出了表格:

    sql> SHOW TABLES; 
    TABLE_NAME | TABLE_SCHEMA  
    BUILDING_DOMAIN | PUBLIC 
    CALENDAR | PUBLIC 
    CAMPUS_DOMAIN | PUBLIC  
    CATEGORY | PUBLIC 
    CONFIGURATION_DOMAIN | PUBLIC 
    DATABASECHANGELOG | PUBLIC 
    DATABASECHANGELOGLOCK | PUBLIC 
    ENTRY_CACHE | PUBLIC 
    ENTRY_CACHE_LINK | PUBLIC  
    ENTRY_DOMAIN | PUBLIC 
    EVENT | PUBLIC 
    EVENT_CATEGORIES | PUBLIC  
    FEED_CACHE | PUBLIC 
    FEED_CACHE_LINK | PUBLIC  
    MS_DEVICE | PUBLIC 
    MS_DEVICEUSER | PUBLIC 
    MS_NMESSAGE | PUBLIC 
    MS_NOTIFICATION | PUBLIC 
    MS_NOT_DEL_REC_DOMAIN | PUBLIC  
    MS_NSTATUS | PUBLIC 
    MS_RECIPIENT | PUBLIC 
    MS_RECIPIENT_STATUSES | PUBLIC  
    NOTIFICATION_DELIVERY_DOMAIN | PUBLIC  
    NUMBERS_DOMAIN | PUBLIC 
    REGISTRATION_CART | PUBLIC 
    SYSTEM_DATA_DOMAIN | PUBLIC 
    (26 rows, 28 ms)
    
  2. 我可以从给定的表中选择行:
    (如下所示,locked 设置为 FALSE)

    sql> SELECT * FROM DATABASECHANGELOGLOCK;
    ID | LOCKED | LOCKGRANTED | LOCKEDBY 
    1 | FALSE | null | null
    (1 row, 1 ms)
    
  3. 由于阅读有效,我尝试写入数据库:

    sql> UPDATE DATABASECHANGELOGLOCK SET LOCKED=FALSE, LOCKGRANTED=null, LOCKEDBY=null where ID=1; 
    
    Error: org.h2.jdbc.JdbcSQLException: The database is read only;
    

tomcat 尝试运行 UPDATE 以获取锁时遇到的错误相同。

如何使 h2 db 默认可用于读写?

【问题讨论】:

  • 您的用户是否对该路径有写权限?
  • 在我的故障排除中,我使用 sudo 运行命令,并且能够查看 H2 DB 的内容,如上所示。 Tomcat 绝对可以访问,因为该文件位于 Tomcat 的子目录中,具有以下权限:rw-r--r--。 1 tomcat tomcat 321536 Oct 20 00:22 banner-mobileserver-prodD.h2.db
  • sudo 到什么帐户?
  • 我在使用 sudo 时没有指定用户,我相信在运行需要提升权限的命令时,该用户在 Red Hat Enterprise 中默认为 root。
  • 它确实(无处不在)。我不记得关于 Tomcat 的具体情况,但我知道如果以 root 身份启动,许多服务器会放弃特权。

标签: java tomcat h2 readonly


【解决方案1】:

我在运行 Tomcat 作为服务的 Windows 服务器上遇到了同样的问题。默认情况下,它作为 LOCAL_SERVICE 帐户运行,该帐户没有对 db 文件夹的写入权限。您可以通过授予 LOCAL_SERVICE 帐户的 db 文件夹修改权限或将服务帐户更改为 LOCAL_SYSTEM 来解决此问题。

【讨论】:

    【解决方案2】:

    添加这个对我有用

    @Configuration
    @EnableJpaRepositories
    @EnableTransactionManagement
    class ApplicationConfig {
    }
    

    【讨论】:

      猜你喜欢
      • 2016-05-05
      • 1970-01-01
      • 1970-01-01
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-14
      相关资源
      最近更新 更多