我在tomcat中使用H2数据库h2-1.4.193作为数据源。
这是我的server.xml
条目:
<Resource auth="Container"
driverClassName="org.h2.Driver"
logAbandoned="true"
maxIdle="10"
maxOpenPreparedStatements="5"
maxTotal="50"
maxWaitMillis="10000"
name="jdbc/shopfloor_local"
password="***" poolPreparedStatements="false"
removeAbandonedOnBorrow="true" removeAbandonedOnMaintenance="true"
removeAbandonedTimeout="180" scope="Shareable" testWhileIdle="true"
timeBetweenEvictionRunsMillis="600000" type="javax.sql.DataSource"
url="jdbc:h2:~/shopfloor;AUTO_SERVER=TRUE;TRACE_LEVEL_SYSTEM_OUT=3"
username="SA"
validationQuery="select 1"/>
我将这个数据源用于DataSourceRealm和我的应用程序。在我的应用程序中,我对序列执行select:
select aufgabenliste_seq.nextval
然后我收到此错误:
2016-12-23 00:46:03 jdbc[3]:
/**/conn3.setAutoCommit(false);
2016-12-23 00:46:03 jdbc[3]:
/**/PreparedStatement prep8 = conn3.prepareStatement("select aufgabenliste_seq.nextval");
2016-12-23 00:46:03 jdbc[3]: Plan : calculate cost for plan [SYSTEM_RANGE:0:org.h2.table.RangeTable@603d6c40]
2016-12-23 00:46:03 jdbc[3]: Plan : for table filter SYSTEM_RANGE:0:org.h2.table.RangeTable@603d6c40
2016-12-23 00:46:03 jdbc[3]: Table : potential plan item cost 1 index PUBLIC.RANGE_INDEX
2016-12-23 00:46:03 jdbc[3]: Plan : best plan item cost 1 index PUBLIC.RANGE_INDEX
2016-12-23 00:46:03 jdbc[3]: Plan : plan cost 2
2016-12-23 00:46:03 jdbc[3]: /**/ResultSet rs9 = prep8.executeQuery();
2016-12-23 00:46:03 lock: 1 exclusive write lock requesting for SYS
2016-12-23 00:46:03 lock: 1 exclusive write lock added for SYS
2016-12-23 00:46:03 lock: 1 exclusive write lock unlock SYS
2016-12-23 00:46:03 lock: 1 exclusive write lock requesting for SYS
2016-12-23 00:46:03 lock: 1 exclusive write lock added for SYS
2016-12-23 00:46:03 jdbc[3]: exception
org.h2.jdbc.JdbcSQLException: Allgemeiner Fehler: "java.lang.RuntimeException: Unexpected code path"
General error: "java.lang.RuntimeException: Unexpected code path"; SQL statement:
select aufgabenliste_seq.nextval [50000-193]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:168)
at org.h2.message.DbException.convert(DbException.java:295)
at org.h2.command.Command.executeQuery(Command.java:213)
at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:110)
at org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:82)
at org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
...
Caused by: java.lang.RuntimeException: Unexpected code path
at org.h2.message.DbException.throwInternalError(DbException.java:242)
at org.h2.message.DbException.throwInternalError(DbException.java:255)
at org.h2.engine.Session.addLock(Session.java:842)
at org.h2.mvstore.db.MVTable.doLock2(MVTable.java:254)
at org.h2.mvstore.db.MVTable.doLock1(MVTable.java:202)
at org.h2.mvstore.db.MVTable.lock(MVTable.java:167)
at org.h2.engine.Database.lockMeta(Database.java:909)
...
...
我已经调试了代码。方法addLock()
中的Session类抛出了异常:
public void addLock(Table table) {
if (SysProperties.CHECK) {
if (locks.contains(table)) {
DbException.throwInternalError();
}
}
locks.add(table);
}
要记录的table
对象包含表SYS
。
为什么在这种情况下请求锁定SYS
失败?
我应该为连接字符串提供其他参数吗?
答案 0 :(得分:0)
我发现这篇文章试图修复Confluence内部h2数据库,并得到了同样的错误,这对我有用。这是我所做的gist on my GitHub外壳程序脚本-您必须根据您的环境进行调整:
#!/bin/bash
# This script has to be run as your confluence user or root
# Create a backup of, and attempt to restore a confluence h2 internal database
# Go home.
cd ~
# Stop confluence
/opt/atlassian/confluence/bin/stop-confluence.sh
# Really though...
pgrep java | xargs kill
#create a good backup of your database files
mkdir -p ~/confluence-db-restore/originals
cp /var/atlassian/application-data/confluence/database/*.db ~/confluence-db-restore/originals
# create another good backup of your database files
tar -cvzf ~/confluence-db-restore/"$(date '+%Y-%m-%d')_h2db_backup.tar.gz" ~/confluence-db-restore/originals
# create a copy of your db to work from
cp ~/confluence-db-restore/originals/*.db ~/confluence-db-restore
# Create recovery SQL script
/opt/atlassian/confluence/jre/bin/java -cp \
/opt/atlassian/confluence/confluence/WEB-INF/lib/h2-*.jar \
org.h2.tools.Recover
# move working files and restore database
mkdir -p ~/confluence-db-restore/recovery
mv *.sql ~/confluence-db-restore/recovery
cd ~/confluence-db-restore/recovery
/opt/atlassian/confluence/jre/bin/java -cp \
/opt/atlassian/confluence/confluence/WEB-INF/lib/h2-*.jar \
org.h2.gools.RunScript -url jdbc:h2:./h2db -user sa -script *.sql
################################################################################
# IMPORTANT THAT YOU MOVE THE RECOVERED DATABASE IF THE RESTORE WAS SUCCESSFUL #
# Uncomment this line to copy the restored database over your existing #
################################################################################
# cp -f ~/confluence-db-restore/recovery/*.db /var/atlassian/application-data/confluence/database/
# chown -R confluence:confluence /var/atlassian/application-data/confluence
systemctl restart confluence