트랜잭션 범위가 너무 일찍 완료됨
트랜잭션 범위 내에서 실행되는 코드 블록을 가지고 있으며 이 코드 블록 내에서 DB에 여러 번 호출합니다.전체 범위를 선택, 업데이트, 생성 및 삭제합니다.삭제를 실행할 때 이 쿼리가 잠재적으로 교착 상태에 빠질 수 있으므로 쿼리가 교착 상태가 되면 자동으로 다시 제출되는 SqlCommand의 확장 메서드를 사용하여 삭제를 실행합니다.
교착 상태가 발생하여 함수가 쿼리를 다시 제출하려고 할 때 문제가 발생한다고 생각합니다.다음과 같은 오류가 표시됩니다.
현재 연결과 관련된 트랜잭션이 완료되었지만 삭제되지 않았습니다.SQL 문을 실행하는 데 연결을 사용하려면 먼저 트랜잭션을 삭제해야 합니다.
쿼리를 실행하는 간단한 코드입니다(아래의 모든 코드는 트랜잭션 범위를 사용하여 실행됨).
using (sqlCommand.Connection = new SqlConnection(ConnectionStrings.App))
{
sqlCommand.Connection.Open();
sqlCommand.ExecuteNonQueryWithDeadlockHandling();
}
교착 상태 쿼리를 다시 제출하는 확장 메서드는 다음과 같습니다.
public static class SqlCommandExtender
{
private const int DEADLOCK_ERROR = 1205;
private const int MAXIMUM_DEADLOCK_RETRIES = 5;
private const int SLEEP_INCREMENT = 100;
public static void ExecuteNonQueryWithDeadlockHandling(this SqlCommand sqlCommand)
{
int count = 0;
SqlException deadlockException = null;
do
{
if (count > 0) Thread.Sleep(count * SLEEP_INCREMENT);
deadlockException = ExecuteNonQuery(sqlCommand);
count++;
}
while (deadlockException != null && count < MAXIMUM_DEADLOCK_RETRIES);
if (deadlockException != null) throw deadlockException;
}
private static SqlException ExecuteNonQuery(SqlCommand sqlCommand)
{
try
{
sqlCommand.ExecuteNonQuery();
}
catch (SqlException exception)
{
if (exception.Number == DEADLOCK_ERROR) return exception;
throw;
}
return null;
}
}
라인에서 오류가 발생합니다.
sqlCommand.ExecuteNonQuery();
트랜잭션 범위에서 선택한 문을 누르는 것을 잊지 마십시오.SQL Server 2005 이상에서는 (nolock)과 함께 사용하는 경우에도 선택한 테이블에 잠금이 계속 생성됩니다.여기에서 트랜잭션 범위를 설정하고 사용하는 방법을 보여줍니다.
using(TransactionScope ts = new TransactionScope
{
// db calls here are in the transaction
using(TransactionScope tsSuppressed = new TransactionScope (TransactionScopeOption.Suppress))
{
// all db calls here are now not in the transaction
}
}
이 메시지는 트랜잭션이 다음 기간보다 더 오래 실행될 때 발생할 수 있습니다.maxTimeout
위해서System.Transactions
그것은 중요하지 않습니다.TransactionOptions.Timeout
증가했습니다. 초과할 수 없습니다.maxTimeout
.
기본값:maxTimeout
는 10분으로 설정되며 해당 값은 에서만 수정할 수 있습니다.machine.config
구성 수준에서 다음을 추가합니다.machine.config
시간 초과를 수정하려면:
<configuration>
<system.transactions>
<machineSettings maxTimeout="00:30:00" />
</system.transactions>
</configuration>
machine.config는 다음 위치에서 찾을 수 있습니다.%windir%\Microsoft.NET\Framework\[version]\config\machine.config
당신은 이 블로그 게시물에서 그것에 대한 더 많은 것을 참조하십시오.
문제를 재현할 수 있습니다.트랜잭션 시간 초과입니다.
using (new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 0, 1)))
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (var sqlCommand = connection.CreateCommand())
{
for (int i = 0; i < 10000; i++)
{
sqlCommand.CommandText = "select * from actor";
using (var sqlDataReader = sqlCommand.ExecuteReader())
{
while (sqlDataReader.Read())
{
}
}
}
}
}
}
던지기System.InvalidOperationException
다음 메시지와 함께:
현재 연결과 관련된 트랜잭션이 완료되었지만 삭제되지 않았습니다.SQL 문을 실행하는 데 연결을 사용하려면 먼저 트랜잭션을 삭제해야 합니다.
이 문제를 해결하려면 쿼리를 더 빨리 실행하거나 시간 초과를 늘립니다.
에서 경발우는생하예 안에서 하면,TransactionScope
롤니다됩백즉. 이 은 ,즉,TransactionScope
완료되었습니다.은 이제 전합다니야금지에 전화해야 .dispose()
새 거래를 시작합니다.저는 솔직히 당신이 오래된 것을 재사용할 수 있을지 모르겠습니다.TransactionScope
시도해 본 적은 없지만, 안 해본 것 같아요.
제 문제는 바보 같은 문제였습니다. 시간 초과로 디버그 브레이크를 밟으면 이것을 얻을 수 있습니다.얼굴 손바닥
프로그래밍을 하면 가끔은 기분이 좋아져요
트랜잭션 시간 초과로 인해 이 오류가 발생할 수 있음을 확인했습니다.Marcus + Rolf가 언급한 것에 추가하자면, 만약 당신이 명시적으로 시간 제한을 설정하지 않았다면.TransactionScope
timeout TimeSpan은 기본값을 가정합니다.이 기본값은 다음 중 작은 값입니다.
로을무경우한을
app.config
/web.config
예:<system.transactions> <defaultSettings timeout="00:05:00" /> </system.transactions>
하만이캡다 '됩지에니 '다것'에서 '.
machine.config
팅세<machineSettings maxTimeout="00:10:00" />
이 예외는 사용 안 함으로 인해 발생할 수도 있습니다. Microsoft Distributed Transaction Coordinator
.
활성화하려면 "dcomcnfg"를 실행하고 다음을 선택합니다."Component Services" -> "My Computer" -> "Distributed Transaction Coordinator" -> "Local Service DTC"
"속성"을 선택합니다.
"원격 클라이언트 허용", "인바운드 허용", "아웃바운드 허용" 및 "인증 필요 없음"을 선택해야 합니다.
언급URL : https://stackoverflow.com/questions/2921920/transactionscope-prematurely-completed
'programing' 카테고리의 다른 글
SQL Server를 사용하여 폴더 내의 파일을 나열하는 방법 (0) | 2023.06.25 |
---|---|
Springboot : BeanDefinitionStore 예외:구성 클래스를 구문 분석하지 못했습니다. (0) | 2023.06.25 |
팬더 read_excel에서 Excel 셀 배경색을 얻으시겠습니까? (0) | 2023.06.25 |
ipython에서 변수를 지우는 방법은 무엇입니까? (0) | 2023.06.25 |
LINQ에서 전체 텍스트 검색(FTS)을 사용할 수 있습니까? (0) | 2023.06.25 |