D.R*_*.R. 19 sql-server sql-server-2012 locking
在另一个应用程序中,我被糟糕的设计震惊了:多个线程EnsureDatabaseSchemaExists()
同时执行一个方法,它看起来基本上是这样的:
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'MyTable') AND type = N'U') BEGIN
CREATE TABLE MyTable ( ... );
END
Run Code Online (Sandbox Code Playgroud)
但是,即使在 SERIALIZABLE 事务中执行,此代码似乎也不是线程安全的(即并行代码尝试多次创建表)。是否有机会强制 SELECT 语句获取阻止另一个线程执行相同 SELECT 语句的锁?
是否有更好的多线程 EnsureSchemaExists() 方法模式?
Pau*_*ite 18
您最好的选择是使用显式包含事务并获取自定义排他锁以使用 sp_getapplock保护整个操作(SELECT
和CREATE TABLE
)。根据设计,系统对象不接受隔离级别请求并以与用户表相同的方式使用锁。
原始代码中的竞争条件是多个线程可以在任何线程到达CREATE TABLE
语句之前得出表不存在的结论。
Rem*_*anu 12
我的建议是尽最大努力尝试/捕获。适当地明确处理重复的情况,例如。忽略它...
真正的问题:为什么 DDL 从多个 xact 按需运行?通常升级和迁移是一个严重的问题,在专用的时间窗口中处理......您不希望您的迁移(代码优先?)意外启动,其中一些更新步骤可能需要几个小时在一个大表上(大小为-数据操作...)
归档时间: |
|
查看次数: |
1424 次 |
最近记录: |