C# 如何避免SMO生成的查询进入死锁模式?
我们有使用SMO进行数据库复制的.Net代码。C# 如何避免SMO生成的查询进入死锁模式?,c#,sql-server,smo,database-deadlocks,C#,Sql Server,Smo,Database Deadlocks,我们有使用SMO进行数据库复制的.Net代码。我们使用SMO从源数据库提取架构,并在目标数据库中创建它们i.IndexKeyType==IndexKeyType.DriPrimaryKey); var scripter=新脚本编写器(服务器); var createTableScript=(null!=pk)?scripter.EnumScript(新的SqlSmoObject[]{table,pk}):scripter.EnumScript(新的SqlSmoObject[]{table});
我们使用SMO从源数据库提取架构,并在目标数据库中创建它们<最近,我们开始收到大量死锁问题
在分析死锁图时,我们发现一些系统基表(例如:sys.sysrowsets)导致了死锁
在进一步的调查中,我们发现..在父数据库上运行的一些SQL作业改变了一些表(如重命名列、创建新列、删除和重新创建索引等),这些表将在内部更新SQL Server基表
同时,我们使用SMO捕获表的定义,这些表在内部又依赖于系统基表
这会导致死锁,SMO是死锁受害者。
我的问题是
var server = new Microsoft.SqlServer.Management.Smo.Server(srcConnection);
var database = server.Databases[MasterDatabaseName];
var table = database.Tables[tableName, schemaName];
var pk = table.Indexes.Cast<Index>().SingleOrDefault(i => i.IndexKeyType == IndexKeyType.DriPrimaryKey);
var scripter = new Scripter(server);
var createTableScript = (null != pk) ? scripter.EnumScript(new SqlSmoObject[] {table, pk}) : scripter.EnumScript(new SqlSmoObject[] {table});
var createTriggersScript = (table.Triggers.Count > 0) ? scripter.EnumScript(table.Triggers.Cast<SqlSmoObject>().ToArray()) : null;
scripter.Options = new ScriptingOptions
{
ScriptData = false,
ScriptSchema = true,
ScriptDrops = true,
IncludeIfNotExists = true
};
var dropTableScript = scripter.EnumScript(new SqlSmoObject[] {table});
var server=new Microsoft.SqlServer.Management.Smo.server(srcConnection);
var database=server.Databases[MasterDatabaseName];
var table=database.Tables[tableName,schemaName];
var pk=table.Indexes.Cast().SingleOrDefault(i=>i.IndexKeyType==IndexKeyType.DriPrimaryKey);
var scripter=新脚本编写器(服务器);
var createTableScript=(null!=pk)?scripter.EnumScript(新的SqlSmoObject[]{table,pk}):scripter.EnumScript(新的SqlSmoObject[]{table});
var createTriggersScript=(table.Triggers.Count>0)?scripter.EnumScript(table.Triggers.Cast().ToArray()):null;
scripter.Options=新脚本选项
{
ScriptData=false,
ScriptSchema=true,
ScriptDrops=true,
IncludeIfNotExists=true
};
var dropTableScript=scripter.EnumScript(新的SqlSmoObject[]{table});
您的SMO代码是什么样子的?您是试图在一次调用中编写整个数据库的脚本,还是单独编写对象的脚本?@BenThul,据我所知,我只编写单个对象的脚本。我如何将示例代码附加到问题的描述中。请检查。如果提取的模式不再代表数据库,您将如何处理它们?换句话说,难道你不能确保你的SMO代码只在作业没有改变数据库的情况下运行吗?死锁是一种症状,不是您的主要问题。@JeroenMostert-我没有提取其架构正在被作业更改的表。这里的问题是由作业持有的系统基表(因为存在架构更改)导致死锁,当我提取静态架构表(请检查死锁图)时,如果您知道有问题的表没有更改,您可以将SMO操作包装在TransactionScope
中,传递隔离级别为可序列化的事务选项(如果一致性很重要)或未提交的事务选项(如果不重要)。免责声明:我还没有测试SMO命令是否可以注册这样的事务。另一个更重且需要企业级的选项是在数据库的某个部分上执行操作?您是试图在一次调用中编写整个数据库的脚本,还是单独编写对象的脚本?@BenThul,据我所知,我只编写单个对象的脚本。我如何将示例代码附加到问题的描述中。请检查。如果提取的模式不再代表数据库,您将如何处理它们?换句话说,难道你不能确保你的SMO代码只在作业没有改变数据库的情况下运行吗?死锁是一种症状,不是您的主要问题。@JeroenMostert-我没有提取其架构正在被作业更改的表。这里的问题是由作业持有的系统基表(因为存在架构更改)导致死锁,当我提取静态架构表(请检查死锁图)时,如果您知道有问题的表没有更改,您可以将SMO操作包装在TransactionScope
中,传递隔离级别为可序列化的事务选项(如果一致性很重要)或未提交的事务选项(如果不重要)。免责声明:我还没有测试SMO命令是否可以注册这样的事务。另一个更重且需要企业级的选项是在数据库的某个部分上执行操作。