Transaction关闭不当可能引发WinForm界面无反应的问题
在WinForm程序中,会对数据库进行一系列的操作。在一个Transaction中,在transaction.Begin()之后,因为try catch的逻辑有问题,在发生异常后,对于这个transaction既没有transaction.rollback(),也没有transaction.commit(). 这时候,有可能程序运行依然正常,但实际上是有问题的。因为这个transaction一直在占用着数据库中的某些表,锁住了某些表。之所以程序还能运行,是因为你目前的一些对于数据库的操作没有用到这些被锁住的表。一旦你再次操作被锁住的表,select,update等,都会出现pending的状态,就是一直在等表的释放。而这些锁是因为无意中的漏洞造成的,是不会释放的,所以,此时,就会出现WinForm的界面无反应问题。这里说的无反应不是说没有动静,而是该程序停留在卡住的状态。
对于Web应用,如果出现了上述transaction没有释放的问题,表现出来的还是比较明显的,在server中会抛出一个request timeout的异常。用户浏览器中也会有相关的信息。
这是一个经验问题,如果在做WinForm开发的时候,点击某个按钮或者其他的什么操作后,出现了界面无反应问题。可能是UI线程后台在进行耗时的操作,大量循环调用COM组件等,也或者是上边提到的数据库transaction没有关闭,这是很容易忽视的一点。所以,如果你的WinForm中有操作数据库,那么可以查看一下是否有这个问题。如何查看?我们可以在界面遇到问题后,到数据库中执行指定的SQL语句,查看当前所有的transaction,基本上如果是因为这个问题造成的,在这里就可以看到那些 没有关闭的transaction.
如果想进一步查看transaction锁定了那些表,可以通过session_id进一步查询
select db_name(resource_database_id) 'DatabaseName', object_name(resource_associated_entity_id) 'TableName', request_type, request_mode, request_status from sys.dm_tran_locks where resource_type='OBJECT' and request_session_id=[进程ID]PS: 关于如何查询block数据库的动作