db에 연결하기 위해 많은 모델을 사용했습니다. 마지막 프로젝트에서는 C #및 amp; 엔티티 프레임 워크, 나는 db 연결에 대한 정적 클래스를 만들었지 만 열 개 이상의 연결 요청이 함께 오면 10-15 개 이상의 요청이 오면 오류가 발생합니다. 모든 정적 메서드와 클래스를 제거했습니다.
이제 나는 알고 싶다.
연결에 가장 적합한 모델은 무엇입니까?
예를 들어나는 sms 발신자 웹 패널에서 일하고, 나는 초당 100K SMS를 보내야한다.이 sms는 다른 사람들과 모여서 모든 패키지에 1 ~ 20 sms를 가지고있다. 그런 다음 1 초당 5K ~ 100K 패키지를 보내야한다. 패키지 난이 단계를 수행해야합니다 :
로그, 사용자 인터페이스 및 모니터링 위젯과 같은 모든 단계와 많은 작업이 수행되어야하며이 트랜잭션을 수행 할 때마다 DB 연결이 필요합니다.
자, DB에 연결하기위한 가장 좋은 모델은 무엇입니까? 인간의 요청이나 스레드 요청 또는 매 트랜잭션마다.
1. Should i close it after every query?
닷넷은 당신을 위해 그것을 처리합니다. 쓰레기 수집 작업입니다. 따라서 수동으로 객체를 폐기해야하는 번거 로움을 피하십시오. Jon Skeet의 좋은 대답입니다.https://stackoverflow.com/a/1998600/544283. 그러나 당신은using(IDisposable){ }
GC가 작업을하도록 강제하는 명령문. 다음은 자원 재 할당에 관한 멋진 기사입니다.http://www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About.
2. A connection in static class is good?
못데이터 컨텍스트를 정적으로 만드십시오! 데이터 컨텍스트아니스레드 안전 또는 동시 안전.
3. Is there a good design pattern for this problem?
Belogix가 의존성 주입과 작업 단위 패턴을 언급했듯이 사실 엔티티 프레임 워크~이다.작업 단위 그 자체. DI와 UoW는 다소 과장되어 있지만 IoC 컨테이너를 처음 다루는 사람이라면 구현하기가 쉽지 않습니다. 또 다른 한 가지는 테스트를 실행하지 않을 경우 DI가 실제로 필요하지 않다는 것입니다. 이러한 패턴의 놀라운 점은 분리되어 땀을 흘리지 않고 테스트하고 조롱 할 수 있습니다.
짧게 : 코드에 대한 테스트를 실행하려는 경우 이러한 패턴을 찾으십시오. 그렇지 않은 경우 원하는 서비스간에 데이터 컨텍스트를 공유하는 방법에 대한 예제를 제공합니다. 이것은 귀하의 네 번째 질문에 대한 해답입니다.
4. What is the best method for making database connection (static, per request)?
컨텍스트 서비스 :
public class FooContextService {
private readonly FooContext _ctx;
public FooContext Context { get { return _ctx; } }
public FooContextService() {
_ctx = new FooContext();
}
}
기타 서비스 :
public class UnicornService {
private readonly FooContext _ctx;
public UnicornService(FooContextService contextService) {
if (contextService == null)
throw new ArgumentNullException("contextService");
_ctx = contextService.Context;
}
public ICollection<Unicorn> GetList() {
return _ctx.Unicorns.ToList();
}
}
public class DragonService {
private readonly FooContext _ctx;
public DragonService(FooContextService contextService) {
if (contextService == null)
throw new ArgumentNullException("contextService");
_ctx = contextService.Context;
}
public ICollection<Dragon> GetList() {
return _ctx.Dragons.ToList();
}
}
제어 장치:
public class FantasyController : Controller {
private readonly FooContextService _contextService = new FooContextService();
private readonly UnicornService _unicornService;
private readonly DragonService _dragonService;
public FantasyController() {
_unicornService = new UnicornService(_contextService);
_dragonService = new DragonService(_contextService);
}
// Controller actions
}
두 번째 생각 (거의 편집) : 당신의 엔티티에 대한 프락시를 만들지 않도록 컨텍스트가 필요하다면, 다음과 같이 컨텍스트 서비스를 과부하시킬 수도 있습니다 :
public class FooContextService {
private readonly FooContext _ctx;
public FooContext Context { get { return _ctx; } }
public FooContextService() : this(true) { }
public FooContextService(bool proxyCreationEnabled) {
_ctx = new FooContext();
_ctx.Configuration.ProxyCreationEnabled = proxyCreationEnabled;
}
}
노트:
편집하다:
일부 독서 첫 번째 :
이것을 완료하십시오 :
(_context as IObjectContextAdapter).ObjectContext.Connection.Open();
이것에 대한 훌륭한 기사입니다.연결 및 트랜잭션 관리.
Entity 프레임 워크는 Connection 속성을 통해 EntityConnection을 노출합니다. 다음으로 읽기 :public sealed class EntityConnection : DbConnection
.
연결 관리에 대한 고려 사항 : (이전 링크에서 가져옴)
희망이 도움이됩니다.
using(IDisposable){ }
GC가 작업을 " using 문이 GC에 아무 것도하지 않도록합니다. - default.kramer"Don't bother disposing your objects manually"
:누가각 객체를 수동으로 처리 하시겠습니까? GC가 각 객체를 수동으로 배치하더라도 GC는 자동으로 아무 것도하지 않으므로 GC를 언제 어떻게 그리고 언제 무료로 사용할 수 있는지에 대해 매우 똑똑하다고 말한 것입니다. 과"use the using{} statement to force the GC to do it's work"
: 당신은 내부의 자원이using
블록이 전화를 걸지 않습니다.Dispose
그것의 범위가 끝날 때 그 자원에 대한 방법? 그렇다면 왜 구현해야 하는가?IDisposable
를 사용할 때using
성명서? 이를 반영하도록 답변을 변경하겠습니다. - EstebanIDisposable
. 에이using
통화 차단Dispose
; GC가 최종자를 호출합니다. 공통의 "안전망" 파이널 라이저가Dispose
불렀지 만 잘 작동하는 응용 프로그램에서는이 안전망이 필요하지 않아야합니다.IDisposables
GC 참여없이 폐기되어야합니다. - default.kramer
귀하의 질문에 대한 답변 :
닫아. .NET은 연결 풀링을 지원합니다.
그것을 창조하십시오. 매번 (연결 conn = new ....)를 사용하여이 방법을 사용하면 .NET 풀링 메커니즘을 최대한 활용할 수 있습니다.
당신은 .NET ThreadPool (또는 당신 자신의 커스텀 하나)을 사용할 수 있고 ThreadPool은 단지 10 개의 스레드를 병렬로 사용하고 Enqueue 작업 항목을 하나씩 사용하도록 정의 할 수 있습니다. 이 방법은 더 이상 다음 10 연결을 같은 시간에 사용됩니다 + 그것은 아마 더 빨리 작동합니다. Custom ThreadPools에 대한 추가 정보 :커스텀 ThreadPool 구현
인스턴스별로.
다음은 아키텍처에 대한 제 제안입니다.
보류중인 SMS를 보낼 데이터베이스 테이블 (대기열)을 만듭니다.
각 행에는 SMS에 필요한 모든 정보와 현재 상태가 포함됩니다.
작업자 프로세스를 생성하십시오. 아마도이 테이블을 샘플링하는 Windows 서비스 일 것입니다. 상태 = '보류 중'(int로 표시되어야 함) 인 TOP20 SMS를 선택합니다. 상태를 '보내기'로 업데이트합니다.
각 SMS는 Windows 서비스 측에서 사용자 정의 스레드 풀을 사용하여 전송됩니다.
프로세스가 끝나면 모든 처리 된 SMS 상태가 CTE (공통 테이블 표현식 - '대량 업데이트'작업을 수행 한 모든 SMS 행 ID와 함께 cte를 보낼 수 있음)를 사용하여 '완료'로 업데이트됩니다. ~ '완료'상태).
상태 업데이트 저장 프로 시저를 'getpending'과 동일한 것으로 만들 수 있습니다. 이렇게하면 잠금없이 선택하여 업데이트 할 수 있고 데이터베이스가 더 빨리 작동 할 수 있습니다.
이 방법을 사용하면 하나 이상의 프로세서 서비스를 실행할 수 있습니다 (하지만 nolock을 풀어야합니다).
가능한 한 많은 잠금을 피하십시오.
그런데 보류중인 SMS 테이블에 행을 추가하기 만하면 시스템의 어느 위치에서나 SMS를 보낼 수 있기 때문에 이것은 또한 좋은 방법입니다.
그리고 한 가지 더요, 엔티티 프레임 워크를 사용하는 것을 권장하지 않습니다. 왜냐하면 두드러기가 너무 많기 때문입니다. 이런 종류의 작업에 필요한 것은 단순히 3-4 개의 저장 프로 시저를 호출하는 것뿐입니다. 어쩌면 한번보세요.닷퍼 닷넷- 대부분의 경우 EF (Entity Framework)보다 10 배 이상 빠르게 작동하는 매우 가벼운 MicroDal 프레임 워크
제 생각에 요청 당 최고로 비싸다고 생각합니다. 스레드 안전 연결 풀을 사용하고 연결 범위를 작업 단위 (UOW)와 일치 시키십시오. 작업 단위 (UOW)가 커밋되거나 롤백 될 때 트랜잭션 동작 및 작업 단위 (UOW)를 담당하는 서비스가 연결을 체크 아웃하여 사용하고 풀로 리턴하십시오.
최신 정보:
상태 업데이트를 수행하는 데 10-12 초가 소요됩니까? 너는 뭔가 잘못 했어. 서면으로 작성한 귀하의 질문은 적절한 대답을 제공하기에 충분하지 않습니다.
매일 NASDAQ 볼륨8 시간짜리 하루에 ~ 45K 트랜잭션까지 작동하는 1.3B 트랜잭션입니다. 귀하의 볼륨은 NASDAQ의 2 배입니다. 하나의 컴퓨터에서이 작업을 수행하려고한다면 NASDAQ이 둘 이상의 서버를 사용하고 있다고 말할 수 있습니다.
또한 ACID를 사용하여 상태를 업데이트하지 않고도 할 수 있는지 궁금합니다. 아무튼,스타 벅스는 2 단계 커밋을 사용하지 않습니다.. 아마도 더 나은 솔루션은 전송 대기 후에 해당 상태를 업데이트하기 위해 차단 대기열과 함께 생산자 / 고객 패턴을 사용하는 것입니다.