PDA

View Full Version : سوال: استفاده از تراکنش ( Transaction ) در سی شارپ



forodo
شنبه 22 شهریور 1393, 13:23 عصر
سلام
روش استفاده از تراکنش داخل سی شارپ به چه شکل است؟
من کدهای زیر رو چطوری می تونم داخل Transaction قرار بدم؟
در اصل اون 4تا تابع داخل if مهمه.
if (SuiterInsertValue() && ServisesInsertValues() && ServisesInsertPeigiri() && InsertTableNameAndCode())
{
MessageBox.Show(
"درخواست شما ثبت شد",
"ثبت درخواست انجام خدمات",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
if (MessageBox.Show("کد پیگیری این درخواست " + peigiri.ToString() + "/" + "27" + " می باشد" + "\n" + "\n" + "آیا می خواهید از فرم پرینت بگیرید؟", "کد پیگیری", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
{
label9.Visible = true;
lblCodep.Text = peigiri.ToString() + "/" + "27";
PrintFromForm PFF = new PrintFromForm();
PFF.pprriinnttLandscape(this, printDocument1, printDialog1, false);
}
this.Close();
}
else
{
MessageBox.Show(
"ثبت درخواست شما با مشکل مواجه شد",
"خطا در ثبت اطلاعات درون بانک اطلاعاتی",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
}

forodo
شنبه 22 شهریور 1393, 19:00 عصر
من می خوام این 4تا تابع داخل تراکنش قرار بگیره.
SuiterInsertValue() && ServisesInsertValues() && ServisesInsertPeigiri() && InsertTableNameAndCode()

mz6488
شنبه 22 شهریور 1393, 19:59 عصر
از چه تکنولوژی استفاده میکنی؟

esafb52
شنبه 22 شهریور 1393, 20:12 عصر
سلام
روش استفاده از تراکنش داخل سی شارپ به چه شکل است؟
من کدهای زیر رو چطوری می تونم داخل Transaction قرار بدم؟
در اصل اون 4تا تابع داخل if مهمه.
if (SuiterInsertValue() && ServisesInsertValues() && ServisesInsertPeigiri() && InsertTableNameAndCode())
{
MessageBox.Show(
"درخواست شما ثبت شد",
"ثبت درخواست انجام خدمات",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
if (MessageBox.Show("کد پیگیری این درخواست " + peigiri.ToString() + "/" + "27" + " می باشد" + "\n" + "\n" + "آیا می خواهید از فرم پرینت بگیرید؟", "کد پیگیری", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
{
label9.Visible = true;
lblCodep.Text = peigiri.ToString() + "/" + "27";
PrintFromForm PFF = new PrintFromForm();
PFF.pprriinnttLandscape(this, printDocument1, printDialog1, false);
}
this.Close();
}
else
{
MessageBox.Show(
"ثبت درخواست شما با مشکل مواجه شد",
"خطا در ثبت اطلاعات درون بانک اطلاعاتی",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
}





public int stratsabt()
{
con.Open();
SqlTransaction transaction;
transaction = con.BeginTransaction();
SqlCommand command = new SqlCommand();
command.Connection = con;
command.Transaction = transaction;
command.CommandType=CommandType.StoredProcedure;
command.CommandText = "createtbl";
int res = command.ExecuteNonQuery();
if (res>0)
{
transaction.Commit();
}
else
{
transaction.Rollback();
}
return res;
}

forodo
شنبه 22 شهریور 1393, 21:22 عصر
public int stratsabt()
{
con.Open();
SqlTransaction transaction;
transaction = con.BeginTransaction();
SqlCommand command = new SqlCommand();
command.Connection = con;
command.Transaction = transaction;
command.CommandType=CommandType.StoredProcedure;
command.CommandText = "createtbl";
int res = command.ExecuteNonQuery();
if (res>0)
{
transaction.Commit();
}
else
{
transaction.Rollback();
}
return res;
}
خوب من کجا می تونم اون 4تا تابع رو قرار بدم؟

esafb52
یک شنبه 23 شهریور 1393, 01:14 صبح
معمولا زمانی از تراکنش ها استفاده میشه که قراره چند تا عملیات باهم انجام بشه و اگر هر کردوم از اونها انجام نشد باید اون تراکنش لغو بشه حالا شما تو متدهاتون ببینین که تمام عملیات های مورد نظر شما انجام میشه اون وقت transaction.Commit();
رو اجرا کن در غیر این صورت transaction.Rollback();

forodo
یک شنبه 23 شهریور 1393, 04:34 صبح
معمولا زمانی از تراکنش ها استفاده میشه که قراره چند تا عملیات باهم انجام بشه و اگر هر کردوم از اونها انجام نشد باید اون تراکنش لغو بشه حالا شما تو متدهاتون ببینین که تمام عملیات های مورد نظر شما انجام میشه اون وقت transaction.Commit();
رو اجرا کن در غیر این صورت transaction.Rollback();
هر 4تا تابع باید اجرا بشه.
اگر یکیش اجرا نشه کلاً قبلی ها هم باید لغو بشه.
یکی بود مشکلی نبود ولی الان که 4تاست داستان شده.

mz6488
یک شنبه 23 شهریور 1393, 06:07 صبح
یا باید هر 4 تا تابع رو یه جا بفرستی به sql یا اینکه در صورت بروز خطا بیاد یه پیغام به کاربر نشون بده و بعدش از نرم افزار حارج بشه.به هر حال باید کاری کنی که احتمال بروز خطا خیلی خیلی کم باشه

forodo
چهارشنبه 26 شهریور 1393, 21:07 عصر
یا باید هر 4 تا تابع رو یه جا بفرستی به sql یا اینکه در صورت بروز خطا بیاد یه پیغام به کاربر نشون بده و بعدش از نرم افزار حارج بشه.به هر حال باید کاری کنی که احتمال بروز خطا خیلی خیلی کم باشه
هیچ راهی نداره که بشه ین 4تا تابع رو انداخت توی تراکنش؟
حتماً باید اون 4تا کوئری جدارو یکی کنم؟

fakhravari
پنج شنبه 27 شهریور 1393, 10:12 صبح
روی یک int res = command.ExecuteNonQuery(); چند بار ExecuteNonQuery کنید و نتایج با if چک کنید و در صورت موفقیط
transaction.Commit(); کنید

forodo
پنج شنبه 27 شهریور 1393, 10:54 صبح
روی یک intres = command.ExecuteNonQuery(); چند بار ExecuteNonQuery کنید و نتایج با if چک کنید و در صورت موفقیط
transaction.Commit(); کنید

درست متوجه نشدم.
میشه برای همون 4تا تابع بگید چه جوری میشه.

محمد آشتیانی
پنج شنبه 27 شهریور 1393, 11:07 صبح
سلام
شما موقعی میتونی با استفاده از تراکنش کوئری ها رو اجرا کنی که همه کوئری ها با یک شیء SqlCommand اجرا شده باشن ، اینکه شما تو هر تابع کانکشن رو باز کنی کوئریت رو اجرا کنی و کانکشنو ببندی ، امکان استفاده از تراکنش رو برای چهارتا تابعت نداری
بنابراین پیشنهادم اینه که اون چهارتا تابع شما هرکدوم یه خروجی بهت برگردونن که کوئری مورد نظرت باشه و نهایتا تو یه تابع دیگه به دیتابیس وصل شو و بعد از ایجاد Transaction خروجی اون چهارتا تابع رو Execute کن. اینطوری میتونی اگر یکی از کوئری ها خطا داد عمل RollBack رو انجام بدی ، اگرم همه درست اجرا شدن که Commit انجام میشه.

forodo
پنج شنبه 27 شهریور 1393, 11:20 صبح
سلام
شما موقعی میتونی با استفاده از تراکنش کوئری ها رو اجرا کنی که همه کوئری ها با یک شیء SqlCommand اجرا شده باشن ، اینکه شما تو هر تابع کانکشن رو باز کنی کوئریت رو اجرا کنی و کانکشنو ببندی ، امکان استفاده از تراکنش رو برای چهارتا تابعت نداری
بنابراین پیشنهادم اینه که اون چهارتا تابع شما هرکدوم یه خروجی بهت برگردونن که کوئری مورد نظرت باشه و نهایتا تو یه تابع دیگه به دیتابیس وصل شو و بعد از ایجاد Transaction خروجی اون چهارتا تابع رو Execute کن. اینطوری میتونی اگر یکی از کوئری ها خطا داد عمل RollBack رو انجام بدی ، اگرم همه درست اجرا شدن که Commit انجام میشه.
نمی تونم متوجه بشم که روی کد چطور می تونم این رو پیاده سازی کنم.
اگر کدش رو بنویسید ممنون می شم.
من تا حالا تو عمرم executenonquery رو توی متغیر نریختم.

محمد آشتیانی
پنج شنبه 27 شهریور 1393, 11:57 صبح
سلام مجدد
ببین دوست عزیز ، منظورم اینه که شما یه متد برای ثبت داشته باشی مثل این

private void ExecuteCommands()
{
SqlTransaction Transaction;
SqlConnection con = new SqlConnection("Your ConnectionString");
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
con.Open();

Transaction = con.BeginTransaction();
cmd.Transaction = Transaction;
try
{
cmd.CommandText = SuiterInsertValue();
cmd.ExecuteNonQuery();
cmd.CommandText = ServisesInsertValues();
cmd.ExecuteNonQuery();
cmd.CommandText = ServisesInsertPeigiri();
cmd.ExecuteNonQuery();

cmd.CommandText = InsertTableNameAndCode();
cmd.ExecuteNonQuery();
Transaction.Commit();
}
catch (Exception ex)
{
Transaction.Rollback();
}
con.Close();

}


شما هرچنتا Command که دلت بخواد میتونی Execute کنی ، من دقیقا نمیدونم توی توابعی که شما نوشتی چه اتفاقی داره میفته ، اما چیزی که اینجا لازم داریم یه تابعی هست که خروجیش string باشه و اونو بجای کوئری توی CommandText بریزی ، مثل این:
ضمن اینکه پیغام های مناسب موفقیت و خطا رو بعد از commit و rollback میتونی نمایش بدی.


private string SuiterInsertValue()
{
string Query = "INSERT INTO YourTable (...) VALUES (...)";
return Query;
}


صد البته که تابع شما با این تفاوت داره ، ولی خروجی تابع مهمه که یه کوئری باشه (توی خود تابع لازم نیست چیزی رو execute کنی)

* کانکشن استرینگ خودت رو تو متد اول جایگزین کن.


موفق باشید.

forodo
پنج شنبه 27 شهریور 1393, 12:36 عصر
این توابع منه:
private bool SuiterInsertValue()
{
UseDate ud = new UseDate();
try
{
SqlConnection objconnection =
new SqlConnection(clsForms.ConnectionString);


SqlCommand objcommand1 = new SqlCommand();

objcommand1.Connection = objconnection;

objcommand1.CommandText = @"INSERT INTO tblServisRequest(
Username, UnitName, SubmitDate, SendTo, TimeSabt)
VALUES(
@Username, @UnitName, @SubmitDate, @SendTo, @TimeSabt)";

objcommand1.Parameters.AddWithValue("@username", Program.Username);
objcommand1.Parameters.AddWithValue("@UnitName", txtUnitName.Text);
objcommand1.Parameters.AddWithValue("@SubmitDate", lblDate.Text);
objcommand1.Parameters.AddWithValue("@SendTo", lblUsernameDarkhast.Text);
objcommand1.Parameters.AddWithValue("@TimeSabt", ud.TimeEightCharacter().ToString());

objconnection.Open();
objcommand1.ExecuteNonQuery();
objconnection.Close();


return true;
}
catch (Exception)
{
return false;
}
}

private bool ServisesInsertValues()
{
try
{
int servisRequestID = GetFinalIDas();

SqlConnection objconnection =
new SqlConnection(clsForms.ConnectionString);


SqlCommand objcommand1 = new SqlCommand();

objcommand1.Connection = objconnection;

objconnection.Open();

objcommand1.CommandText = @"INSERT INTO tblServisRequestServises(
ServisDesc, Amount, Unit,
Survy, UseDesc, ServisRequestID)
VALUES(
@ServisDesc, @Amount, @Unit,
@Survy, @UseDesc, @ServisRequestID)";

for (int i = 0; i < dgvServisRequestServises.Rows.Count - 1; i++)
{
objcommand1.Parameters.Clear();
objcommand1.Parameters.AddWithValue("@ServisDesc", dgvServisRequestServises.Rows[i].Cells["Desc"].Value.ToString());
objcommand1.Parameters.AddWithValue("@Amount", dgvServisRequestServises.Rows[i].Cells["Count"].Value.ToString());
objcommand1.Parameters.AddWithValue("@Unit", dgvServisRequestServises.Rows[i].Cells["Unit"].Value.ToString());
objcommand1.Parameters.AddWithValue("@Survy", dgvServisRequestServises.Rows[i].Cells["CalculatePrice"].Value.ToString());
if (dgvServisRequestServises.Rows[i].Cells["Column1"].Value == null)
objcommand1.Parameters.AddWithValue("@UseDesc", "");
else
objcommand1.Parameters.AddWithValue("@UseDesc", dgvServisRequestServises.Rows[i].Cells["Column1"].Value.ToString());
objcommand1.Parameters.AddWithValue("@ServisRequestID", servisRequestID);

objcommand1.ExecuteNonQuery();
}

objconnection.Close();
return true;
}
catch (Exception)
{
return false;
}
}

private bool ServisesInsertPeigiri()
{
clsForms Forms = new clsForms();
peigiri = GetFinalID();
peigiris = peigiri.ToString() + "/" + "27";
if (Forms.AddPeigiriCode(peigiri, peigiris, "tblServisRequest"))
{
return true;
}
else
{
return false;
}
}
public bool AddPeigiriCode(int p, string pc, string TableName)
{
try
{
SqlConnection objconnection =
new SqlConnection(clsForms.ConnectionString);


SqlCommand objcommand1 = new SqlCommand();

objcommand1.Connection = objconnection;
string str = @"UPDATE " + TableName + " SET PeigiriCode = @PeigiriCode WHERE ID = " + p;
objcommand1.CommandText = str;


objcommand1.Parameters.AddWithValue("@PeigiriCode", pc);


objconnection.Open();
objcommand1.ExecuteNonQuery();
objconnection.Close();

return true;
}
catch (Exception)
{
return false;
}
}

private bool InsertTableNameAndCode()
{
clsForms Forms = new clsForms();
int lidd = GetFinalID();
if (Forms.AddFormNameAndPeigiriCode("frmDarkhastAnjamKhadamat", peigiris, lidd, "انجام خدمات"))
{
return true;
}
else
{
return false;
}
}
public bool AddFormNameAndPeigiriCode(string FormName, string pc, int iidd, string FormNameFarsi)
{
UseDate ud = new UseDate();
try
{
SqlConnection objconnection =
new SqlConnection(clsForms.ConnectionString);


SqlCommand objcommand1 = new SqlCommand();

objcommand1.Connection = objconnection;

objcommand1.CommandText = @"INSERT INTO tblPeigiriCode(
FormNameName, PeigiriCodeCode, peigiriid, FormNameNameFarsi, DateDate, SuiterUsername, TimeSabt)
VALUES(
@FormNameName, @PeigiriCodeCode, @peigiriid, @FormNameNameFarsi, @DateDate, @SuiterUsername, @TimeSabt)";

objcommand1.Parameters.AddWithValue("@FormNameName", FormName);
objcommand1.Parameters.AddWithValue("@PeigiriCodeCode", pc);
objcommand1.Parameters.AddWithValue("@peigiriid", iidd);
objcommand1.Parameters.AddWithValue("@FormNameNameFarsi", FormNameFarsi);
objcommand1.Parameters.AddWithValue("@DateDate", ud.GhamariToShamsi());
objcommand1.Parameters.AddWithValue("@SuiterUsername", Program.Username);
objcommand1.Parameters.AddWithValue("@TimeSabt", ud.TimeEightCharacter().ToString());


objconnection.Open();
objcommand1.ExecuteNonQuery();
objconnection.Close();


return true;
}
catch (Exception)
{
return false;
}
}

forodo
پنج شنبه 27 شهریور 1393, 18:15 عصر
لطفاً دقیق همه کدهارو نگاه کنید ببینید مشکلی نداره؟
یعنی باید اینجوری بنویسم؟
آیا راهه دیگه ای داره که نخوام اینجوری تغییر بدم؟
اگر راه دیگه ای نداشته باشه رسماً به خاک سیاه میشینم چون بحث 10 تا 15 تا نیست. تقریباً 70 یا 80 تاست.
اگر میشه آیا میشه به صورت تابع درآوردش؟
دقت کنید که توش اینسرت و آپدیت دارم.
UseDate ud = new UseDate();
SqlTransaction Transaction;
SqlConnection con = new SqlConnection("Your ConnectionString");
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
con.Open();
Transaction = con.BeginTransaction();
cmd.Transaction = Transaction;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
try
{
cmd.CommandText = @"INSERT INTO tblServisRequest(
Username, UnitName, SubmitDate, SendTo, TimeSabt)
VALUES(
@Username, @UnitName, @SubmitDate, @SendTo, @TimeSabt)";
cmd.Parameters.AddWithValue("@username", Program.Username);
cmd.Parameters.AddWithValue("@UnitName", txtUnitName.Text);
cmd.Parameters.AddWithValue("@SubmitDate", lblDate.Text);
cmd.Parameters.AddWithValue("@SendTo", lblUsernameDarkhast.Text);
cmd.Parameters.AddWithValue("@TimeSabt", ud.TimeEightCharacter().ToString());
cmd.ExecuteNonQuery();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int servisRequestID = GetFinalIDas();
cmd.CommandText = @"INSERT INTO tblServisRequestServises(
ServisDesc, Amount, Unit,
Survy, UseDesc, ServisRequestID)
VALUES(
@ServisDesc, @Amount, @Unit,
@Survy, @UseDesc, @ServisRequestID)";
for (int i = 0; i < dgvServisRequestServises.Rows.Count - 1; i++)
{
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@ServisDesc", dgvServisRequestServises.Rows[i].Cells["Desc"].Value.ToString());
cmd.Parameters.AddWithValue("@Amount", dgvServisRequestServises.Rows[i].Cells["Count"].Value.ToString());
cmd.Parameters.AddWithValue("@Unit", dgvServisRequestServises.Rows[i].Cells["Unit"].Value.ToString());
cmd.Parameters.AddWithValue("@Survy", dgvServisRequestServises.Rows[i].Cells["CalculatePrice"].Value.ToString());
if (dgvServisRequestServises.Rows[i].Cells["Column1"].Value == null)
cmd.Parameters.AddWithValue("@UseDesc", "");
else
cmd.Parameters.AddWithValue("@UseDesc", dgvServisRequestServises.Rows[i].Cells["Column1"].Value.ToString());
cmd.Parameters.AddWithValue("@ServisRequestID", servisRequestID);
cmd.ExecuteNonQuery();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
peigiri = GetFinalID();
peigiris = peigiri.ToString() + "/" + "27";
cmd.CommandText = @"UPDATE tblServisRequest SET PeigiriCode = @PeigiriCode WHERE ID = " + peigiri;
cmd.Parameters.AddWithValue("@PeigiriCode", peigiris);
cmd.ExecuteNonQuery();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int lidd = GetFinalID();
cmd.CommandText = @"INSERT INTO tblPeigiriCode(
FormNameName, PeigiriCodeCode, peigiriid, FormNameNameFarsi, DateDate, SuiterUsername, TimeSabt)
VALUES(
@FormNameName, @PeigiriCodeCode, @peigiriid, @FormNameNameFarsi, @DateDate, @SuiterUsername, @TimeSabt)";
cmd.Parameters.AddWithValue("@FormNameName", "frmDarkhastAnjamKhadamat");
cmd.Parameters.AddWithValue("@PeigiriCodeCode", peigiris);
cmd.Parameters.AddWithValue("@peigiriid", lidd);
cmd.Parameters.AddWithValue("@FormNameNameFarsi", "انجام خدمات");
cmd.Parameters.AddWithValue("@DateDate", ud.GhamariToShamsi());
cmd.Parameters.AddWithValue("@SuiterUsername", Program.Username);
cmd.Parameters.AddWithValue("@TimeSabt", ud.TimeEightCharacter().ToString());
cmd.ExecuteNonQuery();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Transaction.Commit();
}
catch (Exception ex)
{
Transaction.Rollback();
}
con.Close();

محمد آشتیانی
پنج شنبه 27 شهریور 1393, 23:24 عصر
سلام
تابع به اون مفهومی که تو پست اول گفتی نمیشه
این کدت ظاهرا درسته ، اما تست کن ، در واقع شرایطی درست کن که یکی از کوئری ها خطا بده و ببین rollback انجام میشه یا خیر


موفق باشید