H2 数据库,进程死锁导致访问异常的问题

问题现象:

H2数据库启动后,Web Server运行正常,能通过9090端口访问,但无法访问数据库。

问题复现:

通过启动脚本重启H2数据库,复现的概率非常高(测试人员反应运行中的H2数据库也会出现连接异常的问题,该场景暂时未复现)。

问题分析:

初步断定是进程死锁导致。根据程序的堆栈信息,也支持这一判断。

对造成死锁的原因进行分析:

1 H2服务器有多种启动方式,我们使用的是Console模式,且全部使用默认参数;这种场景下,H2会按顺序逐次启动WebServer,TcpServer,PgServer。

WebServer能支持用户通过浏览器访问数据库,TcpServer支持Java程序中通过api访问数据库,PgServer支持通过PgAdmin客户端访问数据库。

2 WebServer启动后,会有一个自我检测的环节,也就是创建一个Socket去连接WebServer,来检测WebServer是否已启动;因此,WebServer的第一个
WebThread线程,就是用来处理这个自检请求的,由于自检请求没有携带正常的启动信息,因此会引发异常,进而去执行DbException.traceThowable()函数。

3 与此同时,Main函数会继续启动TcpServer,过程中会加载org.h2.Driver类;如果此时WebThead线程也恰好正在执行Driver的初始化,就会导致
死锁;如果此时WebThread线程已经执行结束并正常退出,那么Main函数就可以正常的启动TcpServer。

这也就可以解释为什么启动失败是偶发事件。

解决方案:

Console模式的启动顺序是:WebServer->OpenBrowser->TcpServer->PgServer;我们的使用场景中,其实不需要启动浏览器和PgServer;另外,WebServer在TcpServer
之前启动,会偶发启动失败的问题,应该是H2的一个bug。
H2同时提供了另一种启动模式——Server模式,该模式中各服务器的启动顺序是:TcpServer->PgServer->WebServer->OpenBrowser;

因此可以通过Server模式来启动,来避免启动失败的问题。
java -cp $H2HOME/h2-1.4.192.jar org.h2.tools.Server -web -webPort 9090 -webAllowOthers -tcp -tcpPort 9092 –tcpAllowOthers

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值