我们使用 Sybase ASE (15.5) 服务器作为数据库,并且遇到奇怪的间歇性 SPID 阻塞问题,我正在尝试在应用程序层以编程方式检测和缓解这些问题。
Sybase 允许您安排所谓的 "reorgs"据我所知,这是定期重新索引/表压缩、清理等。基本上是定期数据库维护。
每隔一段时间,我们就会让所有行星相互对齐,其中:
- 执行查询(在 Sybase 中创建 SPID)并由于某种原因挂起。这会在
widgets
表上放置一个(阻塞)共享锁;那么 - 计划的重组开始,并想要清理
小部件
表。重组对widgets
发出独占锁定请求,但无法获取锁定,因为widgets
已被锁定并被挂起的 SPID/query 阻塞;那么 - 执行后续查询,每个查询都请求
小部件
上的共享锁;这样 - 整个系统现在已被束缚:重组在获得
widgets
上的独占锁之前无法启动,但widgets
被束缚在阻塞共享锁中由挂起的 SPID。并且由于重组已在widgets
上放置了独占锁,因此想要在widgets
上共享锁的所有其他查询都必须等到重组完成(因为新请求的独占锁胜过新请求的共享锁)。
我认为我的理想策略是:
- 在 2 分钟后超时数据库查询,这将防止 SPID 挂起,从而阻止重组运行;然后
- 如果查询尝试访问具有独占锁的表,请检测到这一点并专门处理它(例如安排查询在 1 小时后再次运行,希望重组完成时等)
我的问题:
- 如何使查询超时以在 2 分钟后释放共享锁?
- 有没有一种方法可以以编程方式(最有可能通过 Sybase JDBC 驱动程序,但也可能通过 Sybase 命令行、HTTP 调用等)确定重组是否正在运行?或者,表上存在排他锁?这样我就可以检测到独占锁并以特殊的方式处理它。
提前致谢!
最佳答案
您可以使用以下查询获取数据库中运行的命令:
select cmd from sysprocesses
要查找锁定信息,您可以加入 master..syslocks
和 your_db..sysobjects
来找出您尝试访问的对象上存在哪些锁。 syslocks.type
指示已到位的锁定类型,这些可能的值可以在此处找到:
select object_name(id), db_name(dbid), type from master..syslocks
where dbid = db_id("your_db")
希望有帮助。
要查找锁是否与重组相关,我认为您应该能够将 syslocks.spid 加入 sysprocesses.spid,其中 cmd =“REORG” 或类似的内容:
select p.cmd, p.spid, l.type from master..sysprocesses p, master..syslocks l where CMD = "REORG"
关于java - Sybase/JDBC : how to detect reorgs or exclusive locks?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18881086/