your programing

SQL Server에서 "with (nolock)"는 무엇입니까?

lovepro 2020. 10. 3. 11:27
반응형

SQL Server에서 "with (nolock)"는 무엇입니까?


누군가 with (nolock)쿼리 에 사용하는 것의 의미를 설명 할 수 있습니까 ?

예를 들어, 거래 율이 높고 특정 테이블에 많은 데이터가있는 뱅킹 애플리케이션이있는 경우 어떤 유형의 쿼리에서 잠금이 해제 될 수 있습니까? 항상 사용하거나 사용하지 않아야하는 경우가 있습니까?


WITH (NOLOCK)는 트랜잭션 격리 수준으로 READ UNCOMMITED를 사용하는 것과 같습니다. 따라서 나중에 롤백되는 커밋되지 않은 행, 즉 데이터베이스로 전송되지 않은 데이터를 읽을 위험이 있습니다. 따라서 다른 작업에 의해 읽기가 교착되는 것을 방지 할 수 있지만 위험이 따릅니다. 거래 율이 높은 은행 애플리케이션에서는 IMHO로 해결하려는 문제에 대한 올바른 해결책이 아닐 수 있습니다.


문제는 더 나쁜 것입니다.

  • 교착 상태 또는
  • 잘못된 값?

재무 데이터베이스의 경우 교착 상태는 잘못된 값보다 훨씬 나쁩니다. 거꾸로 들리는 건 알지만 내 말을 들어요. DB 트랜잭션의 전통적인 예는 두 행을 업데이트하여 하나에서 빼고 다른 행에 더하는 것입니다. 그건 틀렸어요.

금융 데이터베이스에서는 비즈니스 트랜잭션을 사용합니다. 이는 각 계정에 하나의 행을 추가하는 것을 의미합니다. 이러한 트랜잭션이 완료되고 행이 성공적으로 기록되는 것이 가장 중요합니다.

계정 잔액을 일시적으로 잘못 설정하는 것은 큰 문제가 아닙니다. 즉, 종말 조정이 필요합니다. 그리고 계정에서 초과 인출은 데이터베이스에서 커밋되지 않은 읽기보다 한 번에 두 개의 ATM이 사용되기 때문에 발생할 가능성이 훨씬 더 높습니다.

즉, SQL Server 2005는 NOLOCK필요한 대부분의 버그를 수정했습니다 . 따라서 SQL Server 2000 또는 이전 버전을 사용하지 않는 한 필요하지 않습니다.

추가 읽기
행 수준 버전 관리


nolock 힌트의 합법적 인 사용에 대한 교과서 예제는 높은 업데이트 OLTP 데이터베이스에 대한 보고서 샘플링입니다.

화제의 예를 들어 보자. 미국의 대형 하이 스트리트 은행이 은행에서 실행되는 도시 수준의 첫 징후를 찾기 위해 시간별 보고서를 실행하려는 경우 nolock 쿼리는 도시 별 현금 입금 및 현금 인출을 합산하는 트랜잭션 테이블을 스캔 할 수 있습니다. 이러한 보고서의 경우 롤백 된 업데이트 트랜잭션으로 인해 발생하는 오류의 작은 비율은 보고서의 가치를 감소시키지 않습니다.


불행히도 커밋되지 않은 데이터를 읽는 것만이 아닙니다. 백그라운드에서 페이지를 두 번 읽거나 (페이지 분할의 경우) 페이지를 모두 놓칠 수 있습니다. 따라서 결과가 심하게 왜곡 될 수 있습니다.

Itzik Ben-Gan의 기사를 확인 하십시오 . 발췌 내용은 다음과 같습니다.

"NOLOCK 힌트 (또는 세션의 격리 수준을 READ UNCOMMITTED로 설정)를 사용하면 일관성을 기대하지 않는다는 것을 SQL Server에 알릴 수 있으므로 보장 할 수 없습니다."일관되지 않은 데이터 "는 다음을 의미 할뿐만 아니라 나중에 롤백 된 커밋되지 않은 변경 사항이나 트랜잭션의 중간 상태에서 데이터 변경 사항이 표시 될 수 있습니다. 이는 또한 모든 테이블 / 인덱스 데이터를 검색하는 간단한 쿼리에서 SQL Server가 검색 위치를 잃거나 결국 종료 될 수 있음을 의미합니다. 같은 행을 두 번 받고 있습니다. "


데이터베이스 트랜잭션에서 금융 트랜잭션을 래핑하지 않는 이유가 확실하지 않습니다 (한 계정에서 다른 계정으로 자금을 이체 할 때와 같이 한 번에 트랜잭션의 한 쪽을 커밋하지 않습니다. 이것이 명시적인 트랜잭션이 존재하는 이유입니다). 여러분의 코드가 마치 비즈니스 트랜잭션에 대해 생각할 수없는 것처럼 들리더라도 모든 트랜잭션 데이터베이스는 오류 또는 실패시 암시 적 롤백을 수행 할 가능성이 있습니다. 나는이 토론이 당신의 머리 위에 있다고 생각합니다.

잠금 문제가있는 경우 버전 관리를 구현하고 코드를 정리하십시오.

잠금이 없으면 잘못된 값을 반환 할뿐만 아니라 팬텀 레코드와 중복을 반환합니다.

항상 쿼리를 더 빠르게 실행한다는 것은 일반적인 오해입니다. 테이블에 대한 쓰기 잠금이 없으면 아무런 차이가 없습니다. 테이블에 잠금이 있으면 쿼리 속도가 빨라질 수 있지만 처음에 잠금이 발명 된 이유가 있습니다.

공정하게 말하면, nolock 힌트가 유용 할 수있는 두 가지 특별한 시나리오가 있습니다.

1) 라이브 OLTP 데이터베이스에 대해 긴 쿼리를 실행해야하는 2005 년 이전 SQL 서버 데이터베이스가 유일한 방법 일 수 있습니다.

2) 레코드를 잠그고 제어권을 UI 및 판독기에 반환하는 잘못 작성된 애플리케이션은 무기한 차단됩니다. Nolock은 응용 프로그램을 수정할 수없고 (타사 등) 데이터베이스가 2005 년 이전이거나 버전 관리를 켤 수없는 경우 여기에서 유용 할 수 있습니다.


NOLOCK은와 동일 READ UNCOMMITTED하지만 Microsoft는 UPDATE또는 DELETE진술에 사용해서는 안된다고 말합니다 .

UPDATE 또는 DELETE 문의 경우 :이 기능은 향후 버전의 Microsoft SQL Server에서 제거됩니다. 새로운 개발 작업에서는이 기능을 사용하지 말고 현재이 기능을 사용하는 응용 프로그램을 수정하십시오.

http://msdn.microsoft.com/en-us/library/ms187373.aspx

이 문서는 SQL Server 2005에 적용되므로 NOLOCK해당 버전을 사용하는 경우에 대한 지원이 존재합니다. 미래를 대비하여 코드를 작성하기 위해 (더티 읽기를 사용하기로 결정했다고 가정) 저장 프로 시저에서 다음을 사용할 수 있습니다.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED


데이터를 읽을 때만 사용할 수 있으며 아직 커밋되지 않은 데이터를 다시 가져올 지 여부는 신경 쓰지 않습니다.

읽기 작업에서는 더 빠를 수 있지만 실제로 얼마나 많이 말할 수는 없습니다.

일반적으로 사용하지 않는 것이 좋습니다. 커밋되지 않은 데이터를 읽는 것은 기껏해야 약간 혼란 스러울 수 있습니다.


Another case where it's usually okay is in a reporting database, where data is perhaps already aged and writes just don't happen. In this case, though, the option should be set at the database or table level by the administrator by changing the default isolation level.

In the general case: you can use it when you are very sure that it's okay to read old data. The important thing to remember is that its very easy to get that wrong. For example, even if it's okay at the time you write the query, are you sure something won't change in the database in the future to make these updates more important?

I'll also 2nd the notion that it's probably not a good idea in banking app. Or inventory app. Or anywhere you're thinking about transactions.


Simple answer - whenever your SQL is not altering data, and you have a query that might interfere with other activity (via locking).

It's worth considering for any queries used for reports, especially if the query takes more than, say, 1 second.

It's especially useful if you have OLAP-type reports you're running against an OLTP database.

The first question to ask, though, is "why am I worrying about this?" ln my experience, fudging the default locking behavior often takes place when someone is in "try anything" mode and this is one case where unexpected consequences are not unlikely. Too often it's a case of premature optimization and can too easily get left embedded in an application "just in case." It's important to understand why you're doing it, what problem it solves, and whether you actually have the problem.


My 2 cents - it makes sense to use WITH (NOLOCK) when you need to generate reports. At this point, the data wouldn't change much & you wouldn't want to lock those records.


If you are handling finance transactions then you will never want to use nolock. nolock is best used to select from large tables that have lots updates and you don't care if the record you get could possibly be out of date.

For financial records (and almost all other records in most applications) nolock would wreak havoc as you could potentially read data back from a record that was being written to and not get the correct data.


I've used to retrieve a "next batch" for things to do. It doesn't matter in this case which exact item, and I have a lot of users running this same query.


Short answer:

Never use WITH (NOLOCK).

Long answer:

NOLOCK is often exploited as a magic way to speed up database reads, but I try to avoid using it wherever possible.

The result set can contain rows that have not yet been committed, that are often later rolled back.

An error or Result-set can be empty, be missing rows or display the same row multiple times.

This is because other transactions are moving data at the same time you're reading it.

READ COMMITTED adds an additional issue where data is corrupted within a single column where multiple users change the same cell simultaneously.

There are other side-effects too, which result in sacrificing the speed increase you were hoping to gain in the first place.

It can be argued that it is fine to use it in places where you can get away with it, but what's the point? I can't think of any situation where corrupted data is acceptable.

Never ever use NOLOCK ever.

(ever)


Use nolock when you are okay with the "dirty" data. Which means nolock can also read data which is in the process of being modified and/or uncommitted data.

It's generally not a good idea to use it in high transaction environment and that is why it is not a default option on query.


I use with (nolock) hint particularly in SQLServer 2000 databases with high activity. I am not certain that it is needed in SQL Server 2005 however. I recently added that hint in a SQL Server 2000 at the request of the client's DBA, because he was noticing a lot of SPID record locks.

All I can say is that using the hint has NOT hurt us and appears to have made the locking problem solve itself. The DBA at that particular client basically insisted that we use the hint.

By the way, the databases I deal with are back-ends to enterprise medical claims systems, so we are talking about millions of records and 20+ tables in many joins. I typically add a WITH (nolock) hint for each table in the join (unless it is a derived table, in which case you can't use that particular hint)


The simplest answer is a simple question - do you need your results to be repeatable? If yes then NOLOCKS is not appropriate under any circumstances

If you don't need repeatability then nolocks may be useful, especially if you don't have control over all processes connecting to the target database.

참고URL : https://stackoverflow.com/questions/686724/what-is-with-nolock-in-sql-server

반응형