I MVC 컨트롤러에 다음 코드는 자 NHibernate 프레임 워크 사용이 :NHibernate에 트랜잭션이 고립되지
[HttpPost]
public void FinishedExecutingTurn()
{
using (GameUnitOfWork unitOfWork = new GameUnitOfWork())
{
int currentUid = int.Parse(User.Identity.Name);
Game game = unitOfWork.Games.GetActiveGameOfUser(currentUid);
Player localPlayer = game.Players.First(p => p.User.Id == currentUid);
localPlayer.FinishedExecutingTurn = true;
if (game.Players.All(p => p.FinishedExecutingTurn))
{
//do some stuff
}
unitOfWork.Commit();
}
}
세션 당 요청합니다 (HttpContext.Current.Items
에 저장)를 사용하는 것입니다 무엇을 GameUnitOfWork
을 트랜잭션을 시작하십시오.
문제는 두 개의 요청이 동시에 도착할 때 트랜잭션이 고립되어 발생하지 않는 것처럼 보입니다.
2 명의 플레이어가 참여하는 게임입니다. 각 플레이어가 거의 동시에 서버에 요청을 보내는 상황이 있습니다. 트랜잭션은 요청을 보낸 플레이어에서 FinishedExecutingTurn
필드를 true로 설정해야합니다. 두 플레이어가 모두 true로 설정되면 무언가가 발생해야합니다 ("물건을해라").
각 트랜잭션이 분리되어 발생하는 경우 트랜잭션 중 하나가 먼저 발생하여 한 플레이어의 FinishedExecutingTurn
을 true로 설정해야합니다. 그러면 다른 요청의 트랜잭션이 두 번째 플레이어에서 FinishedExecutingTurn
을 true로 설정하고 my if 문 ("do some stuff"). 그러나 양쪽 모두 요청시 FinishedExecutingTurn
이 처음에는 false로 설정 되었기 때문에 가끔 if 문을 입력하지 않는 경우가 있습니다.
내 질문에, 반드시 하나의 트랜잭션이 먼저 발생하고 필드를 true로 설정 한 다음 다른 요청에서 플레이어 중 하나가 이미 true로 설정되어 있어야합니다.
답변을 주셔서 대단히 감사합니다. 이것은 정확히 내가 찾고 있었던 것입니다. 보시다시피, 나는 당신이 게시 한 것과 같은 시간에 내 자신의 질문에 대답했습니다. 내가 이해할 수없는 것은 단순히 "RepeatableRead"를 사용하여 교착 상태가 발생하지 않는다는 것입니다. (처음에는이 코드를 사용하고 있었지만이 트랜잭션은 "RepeatableRead"를 사용하고 모든 것이 올바르게 작동하고 예상대로 작동했습니다)? – Royar
지금 당장 운이 좋지만 교착 상태가 올 것입니다. 오류 로그를 모니터링하거나 더 나은 방법으로 코드를 변경하여 지금 처리하십시오. 플레이어 상태 읽기 후에 브레이크 포인트로 디버깅하거나 스레드를 고정 (스레드 디버그 창 사용), 응용 프로그램을 다시 실행 (F5), 다른 플레이어의 회전 종료, 고정 된 스레드 해동 브레이크 포인트 히트, 그리고 모두 가자. –
@Royar, 고려해야 할 사항 : SQL-Server 구현을 반복적으로 구현하기 위해 작성했습니다. 다른 데이터베이스 엔진은 사물을 잠그는 방식이 다를 수 있으므로 이전에 차단하여 교착 상태가 발생하지 않을 수도 있습니다. 그러나 적어도 반복 읽기의 의미를 존중해야하며, 이는 동시 트랜잭션이 다른 트랜잭션이 완료 될 때까지 다른 트랜잭션이 읽은 데이터를 갱신하는 것을 금지합니다. 이 점을 고려하면 문제가 발생하지 않도록 할 수 있습니다. –