X
تبلیغات
رایتل

Transaction های دات نت

جمعه 19 شهریور 1389 ساعت 01:33

در .NET،transactionها با کلاس System.Data.SqlClient.SqlTransaction کنترل می شوند. باز هم یک transaction روی یک object SqlConnection وجود دارد و بدین ترتیب شما همه objectهای SqlCommand را با استفاده از آن اتصال ایجاد می کنید. بایید نگاهی به این مثال بیاندازیم.

public class TransactionDemo
{
public TransactionDemo()
{

}

[STAThread]
public static void Main()
{
Demo1();
}

private static void Demo1()
{
SqlConnection db = new SqlConnection("connstringhere");
SqlTransaction transaction;

db.Open();
transaction = db.BeginTransaction();
try
{
new SqlCommand("INSERT INTO TransactionDemo " +
"(Text) VALUES ('Row1');", db, transaction)
.ExecuteNonQuery();
new SqlCommand("INSERT INTO TransactionDemo " +
"(Text) VALUES ('Row2');", db, transaction)
.ExecuteNonQuery();
new SqlCommand("INSERT INTO CrashMeNow VALUES " +
"('Die', 'Die', 'Die');", db, transaction)
.ExecuteNonQuery();
transaction.Commit();
}
catch (SqlException sqlError)
{
transaction.Rollback();
}
db.Close();
}

همانطور که در مثال بالا دیدید، ابتدا به یک database متصل شویم. سپس، متد BeginTransaction ازconnection را فرا می خوانیم و مرجعی را به Object که برمی گرداند نگه می داریم. در این نقطه، connection، محدود به object SqlTransaction می شود که برگردانده شده. این بدین معنی است که هر SqlCommand اجرا شده در آن اتصال، در درون transaction خواهد بود. در بلوک (block) try{، می بینید که ما سه object SqlCommand ایجاد و اجرا کردیم. گر چه متوجه خواهید شد که در این مورد ما از این stringهای استفاده می کنیم:

constructor شی SqlCommand دارای یک overload می باشد که شی transaction را به عنوان پارامتر ورودی به آن پاس می دهیم.

دلیلش هم این است که SqlCommand object، نیاز به رد شدن از محدوده transaction به یک connection دارد. قصور در انجام این کار منجر به روی دادن خطای زمان اجرا خواهد شد. به نظر من، این، نقطه ضعف این مدل است، زیرا یک transaction کاملا محدود به connection است، و SqlCommand باید قادر به بیرون کشیدنSqlTransaction object از SqlConnection باشد.

در مثال بالا، در فرمان نخستین SqlCommand کاملا معتبر هستند و TransactionDemo در database وجود دارند. اما جدول CrashMeNow وجود ندارد. از آنجاییکه این جدول وجود ندارد، یک شی SqlException ، روی ExecuteNonQuery، پرتاب خواهد شد. تشخیص اینکه داشتن یک transaction، یک خطای زمان اجرای استاندارد را، که مکانیزم را کنترل می کند، تعویض نمی کند. اگر فکر می کنید ممکن است عبارات شما اجرا نشوند، باید SqlException را catch کنید، و در بلوک catchتان، transaction را به حالت اول برگردانید.

دو عملیات وجود دارد که می توانید روی SqlTransaction object انجام دهید. Rollback، transaction را کنسل و تمامی تغییرات اعمال شده را لغو می کند. Commit، باعث نوشته شدن دایمی transaction در database می شود. هر دو عملیات، باعث اتمام transaction می شوند.

اگر کد بالا را اجرا کنید و به جدول TransactionDemo نگاه کنید، خواهید دید که هیچ ردیفی (row) اضافه نشده است، transaction ، بعد از روی دادن خطای زمان اجرا ،به حالت اول برگردانده شد. اگر خط مزاحم SQL را حذف و برنامه را دوباره اجرا و دوباره به آن نگاه کنید، خواهید دید که دو ردیف اضافه شده است. در واقع بدین معنی است که transaction فعال است.

نظرات (0)
برای نمایش آواتار خود در این وبلاگ در سایت Gravatar.com ثبت نام کنید. (راهنما)

نام :
ایمیل :
وب/وبلاگ :
ایمیل شما بعد از ثبت نمایش داده نخواهد شد