DB 작업에 대한 초보자가 많으므로 기본적인 질문으로 인내심을 가져 주셔서 감사합니다. 로컬 컴퓨터에서 SQL Server 2014를 실행하고 있으며 작은 테이블과 기본 클라이언트 응용 프로그램으로 다양한 접근 방식을 테스트 할 수 있습니다. INSERT INTO
및 UPDATE
문 모두에서 테이블 잠금으로 보이는 것을 얻고 있습니다 . 클라이언트는 다음 코드를 가진 ASP.NET 응용 프로그램입니다.
OleDbConnection cn = new OleDbConnection("Provider=SQLNCLI11; server=localhost\\SQLEXPRESS; Database=<my db>; user id=<my uid>; password=<my pwd>");
cn.Open();
OleDbTransaction tn = cn.BeginTransaction();
OleDbCommand cmd = new OleDbCommand("INSERT INTO LAYOUTSv2 (LAYOUTS_name_t, LAYOUTS_enabled_b, LAYOUTS_data_m) VALUES ('name', '-1', 'data')", cn, tn);
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT SCOPE_IDENTITY()";
int newkey = Decimal.ToInt32((decimal)cmd.ExecuteScalar());
Console.WriteLine("Created index " + newkey);
Thread.Sleep(15000);
tn.Commit();
tn = cn.BeginTransaction();
cmd.CommandText = "UDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key='" + newkey + "'";
cmd.Transaction = tn;
cmd.ExecuteNonQuery();
Console.WriteLine("updated row");
Thread.Sleep(15000);
tn.Rollback();
cn.Close();
이 코드를 실행 한 다음 관리 스튜디오에서 실행 SELECT * FROM LAYOUTSv2
합니다. 클라이언트 스레드가 일시 정지 된 (즉, 커미트 / 롤백 이전) 두 경우 모두 커밋 / 롤백이 발생할 때까지 SELECT 쿼리가 정지됩니다.
테이블에는 기본 키로 지정된 LAYOUTS_key 필드가 있습니다. 속성 창에서 페이지 잠금과 행 잠금이 모두 허용 된 고유하고 클러스터 된 것으로 표시됩니다. 테이블의 잠금 에스컬레이션 설정은 비활성화입니다 ... 테이블과 AUTO의 다른 사용 가능한 설정을 변경하지 않고 시도했습니다. 나는 시도 SELECT ... WITH (NOLOCK)
하고 결과를 즉시 반환하지만 여기 와 다른 곳에서 주의를 기울 이면 내가해야 할 일이 아닙니다. 와 진술 ROWLOCK
에 힌트를 주려고 했지만 아무것도 바뀌지 않았습니다. INSERT
UPDATE
내가 찾고있는 행동은 이것입니다 :의 커밋하기 전에 INSERT
다른 스레드의 쿼리는 에딩중인 행을 제외한 모든 행을 읽습니다 INSERT
. UPDATE
다른 스레드에서 쿼리 를 커밋하기 전에 시작중인 버전의 행을 읽습니다 UPDATE
. 내가 할 수있는 방법이 있습니까? 사용 사례를 명확히하기 위해 다른 정보를 제공해야하는 경우 알려주십시오. 감사.
newkey
가 " something';DELETE FROM LAYOUTSv2 --
"로 설정 되어 있다고 상상해보십시오 . 사용자가 아포스트로피를 삽입하여 쿼리를 조작했기 때문에 업데이트가 성공적으로 완료된 후 테이블을 비 웁니다. 일반적으로 매개 변수화 된 쿼리는 다음과 유사 UDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key=?
하며 ?
코드 의 (매개 변수)에 값을 별도로 할당합니다 .
WHERE LAYOUTS_key='" + newkey + "'
SQL 주입을 포함하여 다양한 이유로 완전한 아니오입니다, 당신은 매개 변수 쿼리를 사용해야합니다.