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句法。当死锁发生后,通过服务端的Trace就可以将死锁信息传到日志。在SQL Server 2000时代,只能通过Trace flag 1204来开启,由于Trace flag 1204并不能提供XML死锁图,在SQL Server 2005以及之后的版本被Trace flag 1222所取代。
为了在服务端针对所有的Session开启Trace flag 1222。可以通过如代码所示。
DBCC TRACEON(1222,-1)
另一种方法是开启Profiler来捕捉,Profiler捕捉到的图示死锁信息内容就更直观了,
评论列表(0条)