前几天在写一个查询时,一个想法出现在我脑海中并一直萦绕在我的脑海中。
什么是可取的,首先检查是否存在唯一列的值,然后插入或插入并让 db 引发唯一约束错误?它甚至会重要吗?
编辑:正如下面在回答这个问题取决于数据库时所建议的那样,我正在添加标签 postgresql。
前几天在写一个查询时,一个想法出现在我脑海中并一直萦绕在我的脑海中。
什么是可取的,首先检查是否存在唯一列的值,然后插入或插入并让 db 引发唯一约束错误?它甚至会重要吗?
编辑:正如下面在回答这个问题取决于数据库时所建议的那样,我正在添加标签 postgresql。
让数据库引发错误。
首先测试对于并发性是不安全的,因为最终会发生冲突,因为 2 个线程可能会通过“NOT EXIST”并且两个线程都会尝试写入。这适用于“READ COMMITTED”和 MVCC/Snapshot 锁定策略。
您可以使用锁定提示来强制隔离,但会降低性能。
我称之为 JFDI 模式(SO 链接)。对于“如果存在则更新”,请参见此处:Need Help Troubleshooting Sql Server 2005 Deadlock Scenario。这些是 SQL Server。MySQL 有 INSERT IGNORE 可以优雅地处理这个问题。不确定其余的
我不认为你的问题真的与数据库无关。正确的答案可能取决于实施细节,这可能因供应商而异,并随着下一个版本而变化。在选择任何 RDBMS 上的任何方法之前,我会在并发下进行测试。
现在,在 SQL Server 2008 R2 上,我正在使用以下内容:
低并发和低修改量。为了保存单行,我使用 sp_getapplock 序列化并使用 MERGE。我在高并发下进行压力测试以验证它是否有效。
更高的并发性和/或容量。为了避免并发和提高性能,我不会一次保存一行。我在我的应用服务器上累积更改,并使用 TVP 保存批次。尽管如此,为了避免与并发相关的问题,我在 MERGE 之前使用 sp_getapplock 进行序列化。再次,我在高并发下进行压力测试以验证它是否有效。
因此,我们在生产中具有良好的性能和零并发相关问题:没有死锁、没有 PK/唯一约束违规等。