(已解决)C3P0数据库使用配置文件链接,报错:com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
本帖简单来说,注意配置的xml文件中的“&”的写法,改成xml文件中支持的“&”即可解决问题。
其他类型的错误排查及排查步骤见下方
因为hibernate和spring等开源框架均使用C3P0来做来创建和管理连接。所以打算自己来体验一下C3P创建的具体过程,在使用C3P0指定的配置文件来创建连接执行简单操作测试时,出现了以下的错误:
四月 11, 2019 8:51:04 上午 com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run 警告: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@204f0fe6 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 四月 11, 2019 8:51:04 上午 com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run 警告: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@204f0fe6 -- APPARENT DEADLOCK!!! Complete Status: ... 四月 11, 2019 8:51:13 上午 com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask run 警告: com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@6fb5efa4 -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception: java.sql.SQLException: No suitable driver ... 四月 11, 2019 8:51:13 上午 com.mchange.v2.c3p0.cfg.C3P0Config initializeIntPropertyVar 信息: '' is not a legal value for property 'maxStatements'. Using default value: 0
本篇博客针对的是配置文件导致的错误,与配置多数据源、嵌套资源释放等问题无关。
在出现上述问题后,进行了问题的逐一排查,下面是关于这个问题的排查与更改步骤:
一 。先排查上述报错中能自己修改的部分,比如第三段报错中关于maxStatements的value的设置
这种书写方式不能不被承认,因为是从网上找来的书写方式(第5条),与默认的书写方式不同(前4条)所以与上面对齐,统一将值直接写在标签内部
二 。我们再来排查第二段报错中的描述无法找到合适的驱动
这里先埋下伏笔,我们一般自己书写配置文件驱动路径的方式是:
在DBCP池中是这样的:
在C3P0中是这样的:
但是在C3P0中如果连接mysql80所需要添加的3个参数,你按照往常使用&符号去连接他们,那么你会得到报错:
[Fatal Error] :5:108: 对实体 "serverTimezone" 的引用必须以 ';' 分隔符结尾。 四月 11, 2019 9:29:24 上午 com.mchange.v2.c3p0.cfg.C3P0Config <clinit> 警告: XML configuration disabled! Verify that standard XML libs are available. org.xml.sax.SAXParseException; lineNumber: 5; columnNumber: 108; 对实体 "serverTimezone" 的引用必须以 ';' 分隔符结尾。
这里就是一个伏笔,因为jee也是这么提示我们的:
所以修改为:
现在报错消失了,但伏笔已经埋下了。。。
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2019.6.6更新
以前不懂事儿,这个不是伏笔,虽然按这篇文章的方式能够解决问题,也就是手动增加配置代码,去设置JdbcUrl,但这种方式虽然解决了问题,但与配置文件的方式背道而驰,不易维护。
其本质是xml中“&”的书写问题...
这是在我使用hibernate配置文件时,配置url看到别人莫名其妙在配置mysql80url时在后面写成了
jdbc:mysql://localhost:3306/hibernate?serverTimezone=GMT&useSSL=false&allowPublicKeyRetrieval=true
这种形式,于是询问别人“&”是什么意思,告知我是xml文件中“&”的写法???于是想起来这篇文章,回来试验了一下,发现解决了问题???
所以当eclipse在xml文件中提示你输入“;”时,请使用正确的连接“&”在xml中格式的“&”即可解决问题。
在此使用纯配置文件的方式即可进行数据库管理,方便多数据源的配置,减少持久化层的修改。
可以搜索一下xml中的一些转义符多了解一下。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
三 。然后首先检查数据库的服务是否已经启动
四 。不使用配置文件方式使用数据池,看是否正常?
测试:
执行成功了,在使用非配置方式来获取连接,竟然就成功了?
五 。将不使用配置成功获得的信息与使用配置失败报错的信息进行对比
发现除了jdbcUrl后面的路径并没有什么不同?(可能就是因为那个第二章提到的断开的 ;?)
又发现了报错:
Caused by: com.mysql.cj.exceptions.WrongArgumentException: Malformed database URL, failed to parse the connection string near '=UTC;useSSL=false'.这个时候如果你的解决思路和我昨晚一样,使用value值把这一段可能会出问题的jdbcUrl传进去,你的问题会更严重,我在测试后发现,信息里你jdbcUrl的默认值会直接为空,这个问题在第一个大标题下已经解决了,不再赘述,是本身xml配置文件的识别问题。
所以,给出如下针对mysql80路径的解决方式,就是常规使用配置文件进行自动配置,但是,如果出现问题,手动增加配置代码,去设置JdbcUrl
结果:
执行成功了,mysql80使用需要配置的这3个参数引发过很多问题,要么不更新使用高版本,要么更换数据库,要么就慢慢排查错误。
网上关于C3P0死锁的解释,关于设置maxstatements在网站中有C3P0开发者自己的一段描述:
https://forum.hibernate.org/viewtopic.php?t=947246&highlight=apparent+deadlock+c3p0
这个swaldman(C3P0开发者),大家可以去这个网站上搜索一下他的发言,来对照一下自己的问题。
2019.6.6内容已修改
修改部分在<<<<<<内容>>>>>>中