我正在编写一些将在生产中运行的日志记录/审核代码(不仅仅是在抛出错误时或在开发时运行)。看完Coding Horror's experiences with dead-locking and logging ,我决定我应该寻求建议。 (杰夫的“不记录”解决方案对我不起作用,这是法律强制的安全审计)
是否有合适的隔离级别来最大限度地减少争用和死锁?我可以将任何查询提示添加到插入语句或存储过程中吗?
我非常关心除审计表之外的所有内容的事务完整性。我们的想法是,将记录如此多的内容,即使少数条目失败,也不是问题。如果日志记录停止了其他一些事务——那就糟糕了。
我可以登录到数据库或文件,尽管登录到文件不太有吸引力,因为我需要能够以某种方式显示结果。不过,记录到文件将(几乎)保证记录不会干扰其他代码。
最佳答案
正常的事务(即READ COMMITTED)插入已经执行了“最小”锁定。插入密集型应用程序不会在插入时出现死锁,无论插入与其他操作混合的顺序如何。在最坏的情况下,密集的插入系统可能会导致发生插入的热点发生页锁争用,但不会导致死锁。
要造成杰夫所描述的死锁,必须有更多因素在起作用,例如以下任何一项:
- 系统正在使用更高的隔离级别(他们当时就已经这样做了,而且这是他们应得的)
- 它们在事务期间从日志表中读取(因此不再是“仅附加”)
- 死锁链涉及应用程序层锁(即 log4net 框架中的 .Net
lock
语句),导致无法检测到的死锁(即应用程序挂起)。鉴于解决问题涉及查看进程转储,我猜这就是他们遇到的情况。
因此,只要您在 READ COMMITTED 隔离级别事务中仅插入日志记录,您就是安全的。如果您期望遇到我怀疑的相同问题(即涉及应用程序层锁的死锁),那么再多的数据库魔法也无法拯救您,因为即使您登录单独的事务或单独的连接,问题仍然可能出现。
关于sql-server - 关于最大限度地减少 MS SQL Server 中仅附加表上的锁定的建议?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/990015/