.NET의 여러 sqlconnections에 단일 sqltransaction을 사용하는 방법은 무엇입니까?
-
03-07-2019 - |
문제
- SQL Server 2000이 있습니다. MultipleActiveringsults를 지원하지 않습니다.
- 여러 인서트를 수행해야하며 삽입 당 하나의 연결로 수행됩니다.
- 모든 삽입 전에 트랜잭션을 시작하고 모든 삽입 후에 마무리하고 싶습니다.
- 어떻게해야하나요?
해결책
하나의 연결과 여러 명령을 사용하지 않는 이유는 무엇입니까 (실제로 하나의 명령이 루프에서 재현 됨)? 이 솔루션은 다음과 같습니다.
public static void CommandExecNonQuery(SqlCommand cmd,
string query, SqlParameter[] prms)
{
cmd.CommandText = query;
cmd.Parameters.AddRange(prms);
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
static void Main(string[] args)
{
string insertQuery =
@"INSERT TESTTABLE (COLUMN1, COLUMN2) " +
"VALUES(@ParamCol1, @ParamCol2)";
using (SqlConnection connection =
new SqlConnection(connectionString))
{
using (SqlCommand command =
connection.CreateCommand())
{
SqlTransaction transaction = null;
try
{
// BeginTransaction() Requires Open Connection
connection.Open();
transaction = connection.BeginTransaction();
// Assign Transaction to Command
command.Transaction = transaction;
for (int i = 0; i < 100; i++)
CommandExecNonQuery(command, insertQuery,
new SqlParameter[] {
new SqlParameter("@ParamCol1", i),
new SqlParameter("@ParamCol2", i.ToString()) });
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
finally
{
connection.Close();
}
}
}
}
또한 참조하십시오
SQL Server Transactions -Ado.net 2.0- 커밋 및 롤백 - 명령문 사용 - idisposable
다른 팁
.NET 2.0을 사용하는지 지정하지 않았지만 그 가정을 할 것입니다. C# 3.0 샘플 코드는 다음과 같습니다.
using (var tx = new TransactionScope()) {
// Execute multiple DB statements inside here
ts.Complete();
}
DB 명령문이 실패하면 Ts.Complete에 도달하지 못하고 사용 명령문 끝에서 트랜잭션이 자동으로 롤백됩니다. 그러나이 접근 방식의 한 가지 경고는 여러 연결을 사용하면 DTC를 활용하게되므로 성능이 느려집니다.
sqltransaction을 트랜잭션 스코프로 변경하기 위해 편집했습니다
DTC 사용을 피하기 위해 단일 SQL 연결을 강제하는 예 :
using (var tx = new TransactionScope())
using (var db = new SqlConnection(connString)) {
// Command 1
using (var cmd = db.CreateCommand()) {
cmd.CommandText = "select...";
using (var reader = cmd.ExecuteReader()) {
// Process results or store them somewhere for later
}
}
// Command 2
using (var cmd = db.CreateCommand()) {
cmd.CommandText = "select...";
using (var reader = cmd.ExecuteReader()) {
// Process results or store them somewhere for later
}
}
// Command 3
using (var cmd = db.CreateCommand()) {
cmd.CommandText = "select...";
using (var reader = cmd.ExecuteReader()) {
// Process results or store them somewhere for later
}
}
tx.Complete();
}
트랜잭션은 연결로 생성되며 연결된 연결을 넘어서는 범위가 없으므로 요청하는 일을 할 수 없습니다. Refactor는 동시에 연결에서 삽입물을 순차적으로 실행하거나 롤백을 달성하기위한 다른 메커니즘을 구현할 수 있도록 refactor. 프로세스)
거래가 여러 연결에 걸쳐있을 수 있다고 생각하지 않습니다.
별도의 연결에서 다중 인서트를 수행 한 이유는 무엇입니까? 나는 당신이 정상적으로 단일 연결로 그들을 원한다고 생각합니다.
제휴하지 않습니다 StackOverflow