unable to close due to unfinalised statements,Qt的SQL模块的问题
造成“unable to close due to unfinalised statements”错误的原因有狠多,本座这里说的是QT的问题。
SQLITE要求,在关闭数据库之前,所有活跃的查询都要终结掉。如果在终结掉那些查询之前就关闭数据库,则关闭 *** 作会失败,并且得到“unable to close due to unfinalised statements”这样的错误。
QT的SQLITE驱动有漏洞,API并没有提供对应的函数来让程序猿显式地终结那些活跃状态的查询对象,而用来关闭数据库连接的
QSqlDatebase::close函数又不做这些终结 *** 作。这样就导致某些(其实狠频繁地出现)情况下无法关闭SQLITE数据库,文件描述符被继
续占用着。而再又打开SQLITE数据库的话,又增加咯程序打开的文件描述符的数量,并且也不能关闭。如此下去,直到文件描述符达到系统限制,终于无法再
连接到SQLITE数据库咯。本座今天碰到的就是这样的问题,从/proc伪文件系统中看到自己的程序打开咯1024个文件,其中绝大部分都是某个
SQLITE数据库文件。
参考这里:https://codereview.qt-project.org/#change,20121
据说QT开发者在QT4.8.2中已经解决咯这个问题,有条件的哥哥们可以升级到QT4.8.2试试,本座目前用的是QT4.8.1,要等到QtSDK中的QT版本升级到4.8.2才能升级。像本座这样没条件升级的哥哥就要用另外的办法来绕过咯。
要绕过也简单,对于同一个SQLITE数据库,在程序中打开一个SQLITE数据库连接之后,一直用这个连接,不再关闭,到最后程序退出的时候再关闭SQLITE连接。那个时候,在关闭之前销毁所有存在的查询对象,就可以正常关闭SQLITE数据库咯。
总之,在升级到QT4.8.2之前,不要频繁关闭SQLITE数据库,那是无用功。
SQLite做为客户端应该很给力,但如果做为服务端应用,在并发处理上会伤感情的。
1、查看数据库锁,诊断锁的来源及类型:select object_id,session_id,locked_mode from v$locked_object
或者用以下命令:
select b.owner,b.object_name,l.session_id,l.locked_mode
from v$locked_object l, dba_objects b
where b.object_id=l.object_id 2、找出数据库的serial#,以备杀死:
select t2.username,t2.sid,t2.serial#,t2.logon_time
from v$locked_object t1,v$session t2
where t1.session_id=t2.sid order by t2.logon_time3、杀死该session
alter system kill session 'sid,serial#'
记得以上是用SYS或者SYSTEM账户进入,要不没权限。
MySQL的表锁定代码是不会死锁的。 MySQL使用表级锁定(而不是行级锁定或列级锁定)以达到很高的锁定速度。对于大表,表级锁定对大多数应用程序来说比行级锁定好一些,但是当然有一些缺陷。 在MySQL3.23.7和更高版本中,一个人能把行插入到MyISAM表同时其他线程正在读该表。注意,目前只有在表中内有删除的行时才工作。 表级锁定使很多线程能够同时读一个表,但是如果一个线程想要写一个表,它必须首先得到独占存取权。在更改期间,所有其他想要存取该特定表的线程将等到更改就绪。 因为数据库的更改通常被视为比SELECT更重要,更新一个表的所有语句比从一个表中检索信息的语句有更高的优先级。这应该保证更改不被“饿死”,因为一个人针对一个特定表会发出很多繁重的查询。 从MySQL 3.23.7开始,一个人可以能使用max_write_lock_count变量强制MySQL在一个表上一个特定数量的插入後发出一个SELECT。 对此一个主要的问题如下: 一个客户发出一个花很长时间运行的SELECT。 然後其他客户在一个使用的表上发出一个UPDATE;这个客户将等待直到SELECT完成。 另一个客户在同一个表上发出另一个SELECT语句;因为UPDATE比SELECT有更高的优先级,该SELECT将等待UPDATE的完成。它也将等待第一个SELECT完成! 对这个问题的一些可能的解决方案是: 试著使SELECT语句运行得更快;你可能必须创建一些摘要(summary)表做到这点。 用--low-priority-updates启动mysqld。这将给所有更新(修改)一个表的语句以比SELECT语句低的优先级。在这种情况下,在先前情形的最後的SELECT语句将在INSERT语句前执行。 你可以用LOW_PRIORITY属性给与一个特定的INSERT、UPDATE或DELETE语句较低优先级。 为max_write_lock_count指定一个低值来启动mysqld使得在一定数量的WRITE锁定後给出READ锁定。 通过使用SQL命令:SET SQL_LOW_PRIORITY_UPDATES=1,你可从一个特定线程指定所有的更改应该由用低优先级完成。见7.25 SET OPTION句法。 你可以用HIGH_PRIORITY属性指明一个特定SELECT是很重要的。见7.12 SELECT句法。 如果你有关于INSERT结合SELECT的问题,切换到使用新的MyISAM表,因为它们支持并发的SELECT和INSERT。 如果你主要混合INSERT和SELECT语句,DELAYED属性的INSERT将可能解决你的问题。见7.14 INSERT句法。 如果你有关于SELECT和DELETE的问题,LIMIT选项的DELETE可以帮助你。见7.11 DELETE句法。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)