Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.
事务阻塞可能会导致死锁。出现死锁情况时,一组事务将进入一种特殊状态,在该状态下这些事务都不能继续执行。
有两个原因会导致死锁:
循环阻塞冲突 事务 A 被事务 B 阻塞,而事务 B 又被事务 A 阻塞。等待并不能解决这个问题,必须取消其中一个事务,使另一个事务能够继续执行。如果多个(大于二)事务出现循环阻塞,也会导致这种情况。
为消除事务死锁,SQL Anywhere 会从陷入死锁的连接中选择一个连接,回退对该连接上活动事务的更改并返回错误。SQL Anywhere 使用内部启发式算法选择要回退的连接,该算法优先选择剩余阻塞等待时间最少的连接(由 blocking_timeout 选项确定)。如果所有连接均设置为始终等待,那么促使服务器检测到死锁的连接会被选作牺牲品连接。
所有工作线程被阻塞 事务被阻塞时,不会释放其工作线程。例如,如果数据库服务器配置了三个工作线程,而事务 A、B 和 C 在当前未执行请求的事务 D 上受到阻塞,由于没有可用工作线程,将出现死锁情况。这种情况称为线程死锁。
假定数据库服务器有 n 个工作线程。当 n-1 个工作线程被阻塞,并且最后一个工作线程也即将被阻塞时,就会发生线程死锁。数据库服务器的内核不会允许这最后一个工作线程被阻塞,因为这样会导致所有工作线程都被阻塞,数据库服务器将因此而挂起。数据库服务器会转而结束即将阻塞最后一个工作线程的任务,回退对该连接上的活动事务的更改,并返回错误(SQLCODE -307、SQLSTATE 40W06)。
如果因数据库大小或阻塞问题而出现很多长时间运行的请求,则具有数十个或数百个连接的数据库服务器可能会出现线程死锁。在这种情况下,提高数据库服务器的进程并发水平可能是一个合适的解决方案。由于可能会出现过度争用或意外争用,因此应用程序的设计也可能会导致线程死锁。在这些情况下,将应用程序调整到更大的数据集可能会使问题更加糟糕,而提高数据库服务器的进程并发水平可能也无法解决该问题。
服务器使用的数据库线程数取决于各个数据库的设置。
如何确定那些连接被阻塞在死锁中从 Sybase Central 查看死锁