2017-02-28 2 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에서는 배치 SQL 쿼리에 GO 문을 사용할 수 있지만 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

관련 문제