2017-02-28 43 views
1

我在我的项目中使用C#,EF和Microsoft SQL Server。我需要将整个数据库锁定在其中一台机器上以使其与Active Directory同步。锁定数据库,使用C#

许多机器都可以访问数据库,所以我需要防止从另一台机器读取,插入或更新我的数据库。

简单的例子,我现在做:

using (DB context = new DB()) 
using (var ts = context.Database.BeginTransaction(System.Data.IsolationLevel.Serializable)) 
{ 
    context.Database.Connection.Open(); 

    try 
    { 
     string sql = SQLProperties.getInstance().CurrentPropeties["User_Insert"]; 
     StringBuilder sb = new StringBuilder(10240); 

     for (int chunkCount = 0; chunkCount < Math.Ceiling((decimal)count/commitCount); chunkCount++) 
     { 
      using (SqlCommand command = new SqlCommand()) 
      { 
       command.Transaction = (SqlTransaction)ts.UnderlyingTransaction; 

       for (var i = 1; i <= commitCount; i++) 
       { 
        string query = sql; 
        int ind = chunkCount * commitCount + i; 

        query = string.Format(query, ind); 

        sb.Append(query); 
        //fill command.Params 
       } 

       command.Connection = (SqlConnection)context.Database.Connection; 
       command.CommandText = sb.ToString(); 

       command.ExecuteNonQuery(); 
      } 

      sb.Clear(); 
     } 

     ts.Commit(); 
    } 
    catch (Exception ex) 
    { 
     ts.Rollback(); 
    } 
} 

但当ExecuteNonQuery()被调用时,将查询发送到数据库和执行。当我准备SqlCommand时,即使我使用单个事务,另一台机器也可以读取,插入或更新数据库中的数据。我需要禁用它。

另外我需要做的很多与数据库中的表中的数据的更改,所以我希望在同步锁定整个数据库。

我知道在Server Management Studio中,我可以使用GO语句进行批量SQL查询,但SqlCommand不支持这一个语句。此外,我尝试使用此方法发送GO语句:

ServerConnection svrConnection = new ServerConnection((SqlConnection)context.Database.Connection); 
Server server = new Server(svrConnection); 
int f = server.ConnectionContext.ExecuteNonQuery("LOCK TABLES dbo.User WRITE"); 

但似乎它不起作用。

如何从C#代码执行此操作?

增加:我如何能同步两个可能的交易在同一时间开始?现在我有一个事务,当一个事务开始在表中插入用户时,例如,在500个用户之后,另一个事务插入用户和表包含来自两个事务的混合数据。我如何订购他们?

+1

GO不是t-sql语句。它是SSMS中的默认批终止符。你的问题是什么? –

+0

我很想知道为什么你需要锁定整个数据库(甚至是所有数据库中的单个表)。大多数现代数据库系统(包括SQL Server)允许非常好的并发性。你想通过锁定整个事物来防止什么现象? –

+0

同步可以同时从两台机器启动,但它们都具有用于同步的公共数据。我需要锁定一些表格以防止双重插入的数据。 这就是为什么我想拒绝访问表。同步数据可能包含10 000多个用户和电子邮件,还需要删除旧数据或将其升级到新状态。 或者我可以用大量的sql查询构建文件并在一个事务中处理它以防止数据库锁定? SqlCommand对像C#中的2100这样的参数有限制。 –

回答

2

如果你确实需要锁定数据库,你可以使用ALTER DATABASE [xyz] SET SINGLE_USER命令。这将限制其他用户连接到数据库的能力。

+0

感谢您的回答!我认为这个解决方案会很好,但是我有可能锁定数据库中的某些表吗? –

+0

如果你想在表上发行锁,你应该可以,但是这是不必要的,因为没有其他用户可以做任何事情或连接。 – SpaceUser7448