.net의 거래
C # .Net 2.0에서 트랜잭션을 수행하는 최상의 방법은 무엇입니까? 사용해야하는 수업은 무엇입니까? 커밋하고 롤백하는 모든 것들 등을 찾아야 할 함정은 무엇입니까? DB에 데이터를 삽입하는 동안 트랜잭션을 수행해야 할 프로젝트를 시작하고 있습니다. 거래에 대한 기본 사항에 대한 답변이나 링크는 환영합니다.
두 가지 주요 거래 유형이 있습니다. 연결 트랜잭션 및 주변 트랜잭션. 연결 트랜잭션 (예 : SqlTransaction)은 db 연결 (예 : SqlConnection)에 직접 연결됩니다. 즉, 연결을 계속 전달해야합니다. 경우에 따라 OK이지만 "만들기 / 사용 / 릴리스"는 허용하지 않습니다. 크로스 DB 작업을 허용하지 않습니다. 예 (공백 형식) :
using (IDbTransaction tran = conn.BeginTransaction()) {
try {
// your code
tran.Commit();
} catch {
tran.Rollback();
throw;
}
}
너무 지저분하지는 않지만 연결 "conn"으로 제한됩니다. 다른 메소드를 호출하려면 "conn"을 전달해야합니다.
대안은 주변 거래입니다. .NET 2.0의 새로운 기능인 TransactionScope 개체 (System.Transactions.dll)는 다양한 작업에서 사용할 수 있습니다 (적절한 공급자는 주변 트랜잭션에 자동으로 참여 함). 이를 통해 기존 (트랜잭션이 아닌) 코드를 쉽게 개조하고 여러 공급자와 대화 할 수 있습니다 (여러 개와 대화 할 경우 DTC가 관여하지만).
예를 들면 다음과 같습니다.
using(TransactionScope tran = new TransactionScope()) {
CallAMethodThatDoesSomeWork();
CallAMethodThatDoesSomeMoreWork();
tran.Complete();
}
여기서 두 가지 방법은 자체 연결 (개방 / 사용 / 닫기 / 처리)을 처리 할 수 있지만 아무 것도 전달하지 않아도 자동으로 주변 트랜잭션의 일부가됩니다.
코드 오류가 발생하면 Dispose ()가 Complete ()없이 호출되므로 롤백됩니다. 내부 트랜잭션을 롤백 할 수는 없지만 외부 트랜잭션을 완료 할 수는 있지만 예상되는 중첩 등이 지원됩니다. 누군가가 행복하지 않으면 트랜잭션이 중단됩니다.
TransactionScope의 다른 장점은 데이터베이스에만 국한되지 않는다는 것입니다. 모든 트랜잭션 인식 공급자가 사용할 수 있습니다. 예를 들어 WCF. 또는 트랜잭션 스코프 호환 객체 모델도 있습니다 (예 : 롤백 기능이있는 .NET 클래스-아마도이 방법을 사용한 적이 없지만 메멘토보다 쉽습니다).
대체로 매우 유용한 객체입니다.
몇 가지주의 사항 :
- SQL Server 2000에서 TransactionScope는 즉시 DTC로 이동합니다. 이것은 SQL Server 2005 이상에서 수정되었으며, DTC로 올라갈 때 2 개의 소스 등과 대화 할 때까지 LTM (훨씬 적은 오버 헤드)을 사용할 수 있습니다.
- 연결 문자열을 조정해야 할 수도 있는 결함 이 있습니다.
protected void Button1_Click(object sender, EventArgs e)
{
using (SqlConnection connection1 = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\Database.mdf;Integrated Security=True;User Instance=True"))
{
connection1.Open();
// Start a local transaction.
SqlTransaction sqlTran = connection1.BeginTransaction();
// Enlist a command in the current transaction.
SqlCommand command = connection1.CreateCommand();
command.Transaction = sqlTran;
try
{
// Execute two separate commands.
command.CommandText =
"insert into [doctor](drname,drspecialization,drday) values ('a','b','c')";
command.ExecuteNonQuery();
command.CommandText =
"insert into [doctor](drname,drspecialization,drday) values ('x','y','z')";
command.ExecuteNonQuery();
// Commit the transaction.
sqlTran.Commit();
Label3.Text = "Both records were written to database.";
}
catch (Exception ex)
{
// Handle the exception if the transaction fails to commit.
Label4.Text = ex.Message;
try
{
// Attempt to roll back the transaction.
sqlTran.Rollback();
}
catch (Exception exRollback)
{
// Throws an InvalidOperationException if the connection
// is closed or the transaction has already been rolled
// back on the server.
Label5.Text = exRollback.Message;
}
}
}
}
트랜잭션을 자체 저장 프로 시저로 래핑하고 C # 자체에서 트랜잭션을 수행하는 대신 해당 방식으로 처리 할 수도 있습니다.
DB 관련 항목에 필요한 경우 일부 OR 매퍼 (예 : NHibernate)는 기본적으로 트랜스 액 티노를 기본적으로 지원합니다.
또한 필요한 것에 따라 다릅니다. 기본 SQL 트랜잭션의 경우 코드에서 BEGIN TRANS 및 COMMIT TRANS를 사용하여 TSQL 트랜잭션을 시도 할 수 있습니다. 이것이 가장 쉬운 방법이지만 복잡하지만 제대로 커밋 (및 롤백)해야합니다.
I would use something like
SQLTransaction trans = null;
using(trans = new SqlTransaction)
{
...
Do SQL stuff here passing my trans into my various SQL executers
...
trans.Commit // May not be quite right
}
Any failure will pop you right out of the using
and the transaction will always commit or rollback (depending on what you tell it to do). The biggest problem we faced was making sure it always committed. The using ensures the scope of the transaction is limited.
참고URL : https://stackoverflow.com/questions/224689/transactions-in-net
'Programing' 카테고리의 다른 글
Ruby 및 / 또는 Rails에서 사용자 정의 오류 유형을 정의 할 위치는 어디입니까? (0) | 2020.06.20 |
---|---|
최종 정적 및 정적 최종의 차이점 (0) | 2020.06.20 |
IIS7에서 폴더 및 확장마다 정적 콘텐츠 캐시를 구성하는 방법은 무엇입니까? (0) | 2020.06.20 |
자바 스크립트 : 페이지의 모든 DOM 요소를 반복하는 방법은 무엇입니까? (0) | 2020.06.20 |
jquery는 클래스와 가장 가까운 이전 형제를 찾습니다. (0) | 2020.06.20 |