نمایش نتایج 1 تا 8 از 8

نام تاپیک: commit کردن موقت transaction

  1. #1
    کاربر دائمی آواتار ozzy_mra
    تاریخ عضویت
    مهر 1388
    محل زندگی
    تهران
    پست
    544

    commit کردن موقت transaction

    با سلام
    من تو یه حلقه foreach دارم یه دستور اینزرت رو به کمک تراکنش اجرا می کنم ، می خوام اگه عملیات مورد نظرم برای تمام عناصر حلقه انجام بشه تراکنش commit بشه ولی برنامه برای عنصر دوم حلقم هنگ میکنه چون قبلی commit kani
    می خواستن بدونم راهی هست که تراکنش رو به صورت موقت commit کنه و در صورتی که تمام عناصر حلقه با موفقیت commit موقت شد کل تراکنش commit بشه؟

  2. #2
    کاربر دائمی آواتار ozzy_mra
    تاریخ عضویت
    مهر 1388
    محل زندگی
    تهران
    پست
    544

    نقل قول: commit کردن موقت transaction

    اصلاً برای این کار که میگم چه راهی رو پیشنهاد می کنید؟
    من یه دیتا تیبل دارم که با یک سری از اطلاعات کاربر که ورود اطلاعات شده پر شده، قراره این دیتا تیبل با بارسی شرایط خاصی در دیتا بیس ذخیره بشه . برای این کار من اونو به یه حلقه foreach پاس می دم که برای هر سطر یه شرطی رو کنترل کنه و این شرط ایطور چک میشه که یه مقدار خاص از دیتابیس گرفته میشه با مقداری که من دارم کنترل میشه اگه شرایط ok بود در دیتا بیس ذخیره میشه ولی اگر برای یه سطر این شرط برقرار نباشه تمام مقادیری که در دیتابیس نوشته شده باید rollback بشه و شرط commit شدن اینه که تمام سطر ها بدون مشکل و با برقرار بودن شرط کنترل شده تو دیتا بیس ذخیره بشند
    من خوده از sqlTransaction استفاده کردم ولی برای سطر دوم به بعد چون وضعیت تراکنش مشخص نیست یعنی نه commit شده و نه rollback شده سیستم هنگ میکنه (که حق داره!)
    نمی دونم دیگه چکار کنم خودم یه راه حل به ذهنم رسید که تو یه لیست ID سطر و مقداری که تغییر کرده رو ذخیره کنم و هر وقت شرط برقرار نشد دوباره به مقداری که اضافه کردم همونو کم کنم ولی راه حل خوبی نیست.
    لطفاً اگه پیشنهادی دارید راهنماییم کنید

  3. #3

    نقل قول: commit کردن موقت transaction

    سلام.
    کاش کدتون رو میذاشتید تا ببینم چطور کد رو نوشته اید. به کد زیر دقت کنید:


    using (SqlConnection connection = new SqlConnection(cnnStr))
    {
    connection.Open();
    using (SqlTransaction trans = connection.BeginTransaction())
    {
    for (int i = 0; i < 5; i++)
    {
    string sql = "INSERT INTO myTable(\"Name\") VALUES(@Name)";
    using (SqlCommand command = new SqlCommand(sql, connection, trans))
    {
    command.Parameters.Add("Name", SqlDbType.NVarChar, 20).Value = i == 3 ? (object)DBNull.Value : i.ToString();
    command.ExecuteNonQuery();
    }
    }

    trans.Commit();
    }
    }


    اینجا، من در یک حلقه، Insert های مورد نظر رو انجام میدم، و از قصد کاری کرده ام که وقتی i==3 بود، مقدار NULL در فیلد ذخیره بشه. فرض می کنیم فیلد هم Nullable نیست. در نتیجه، اینجا Exception ای Throw میشه و چون Transaction کامیت نشده، کل Insert های انجام شده بطور خودکار Rollback میشه. در نتیجه، هیچ Row ای در بانک ذخیره نمیشه. اگر کد فوق مشکلتون رو حل نکرد، لطفا کدی که نوشته ای رو همینجا ضمیمه کنید تا ببینم مشکل چیه.

    موفق باشید.

  4. #4
    کاربر دائمی آواتار ozzy_mra
    تاریخ عضویت
    مهر 1388
    محل زندگی
    تهران
    پست
    544

    نقل قول: commit کردن موقت transaction

    اون sp هم که نوشتم اینه
    یه نگاهی لطفاً بهش بندازید.
    میتونم اینو جایگزین کد های بالا کنم؟
    create procedure insertArticle(
    @articles dbo.artikleInfo readonly,
    @InsertUser decimal(18,3),
    @sanadID bigint)
    as
    declare @kolcode nvarchar(200),@moinCode nvarchar(200),@tafCode nvarchar(200),@jozCode nvarchar(200),@sharh nvarchar(500)
    declare @bed bigint,@bes bigint
    declare @sarfaslId int,@mahiat int
    declare @jambed bigint,@jambes bigint
    declare @errorSTR nvarchar(500)
    declare @Error int
    --------------------------------------------------
    begin tran tran1
    declare @loopCnt int
    select @loopCnt=MAX(id) from @articles
    declare @i int
    set @i=1
    while @i <= @loopCnt
    begin
    select @kolcode=koleKode,@moinCode=moinKode,@tafCode=tafK ode,@jozCode=jozKode,@sharh=sharhArt,@bed=bedArt,@ bes=BesArt
    from @articles
    where id=@i

    set @Error=@@ERROR
    if @Error<>0
    begin
    goto done
    end
    /*کنترل سرفصل ابتدا استخراج کلید اصلی سرفصل*/
    -----------------------------------------------
    if @jozCode=''
    begin
    SELECT @jambed=utblSarfasl.jamBed,@jambed=utblSarfasl.jam Bes,@mahiat=utblMahiat.MahiatSN,@sarfaslId=utblSar fasl.SarfaslSN FROM utblMahiat INNER JOIN utblKol ON utblMahiat.MahiatSN = utblKol.MahiatID INNER JOIN utblSarfasl ON utblKol.KolSN = utblSarfasl.KolID INNER JOIN utblMoin ON utblSarfasl.MoinID = utblMoin.MoinSN INNER JOIN utblTafzili ON utblSarfasl.tafziliID = utblTafzili.TafziliSN where utblKol.KolCode=@kolcode and utblmoin.MoinCode=@moinCode and utblTafzili.TafziliCode=@tafCode and utblsarfasl.jozid=-1
    end
    else
    begin
    SELECT @jambed=utblSarfasl.jamBed,@jambed=utblSarfasl.jam Bes,@mahiat=utblMahiat.MahiatSN,@sarfaslId=utblSar fasl.SarfaslSN FROM utblMahiat INNER JOIN utblKol ON utblMahiat.MahiatSN = utblKol.MahiatID INNER JOIN utblSarfasl ON utblKol.KolSN = utblSarfasl.KolID INNER JOIN utblMoin ON utblSarfasl.MoinID = utblMoin.MoinSN INNER JOIN utblTafzili ON utblSarfasl.tafziliID = utblTafzili.TafziliSN INNER JOIN utblJoz ON utblSarfasl.JozID = utblJoz.JozSN where utblKol.KolCode=@kolcode and utblmoin.MoinCode=@moinCode and utblTafzili.TafziliCode=@tafCode and utblJoz.JozCode=@jozCode
    end

    set @Error=@@ERROR
    if @Error<>0
    begin
    goto done
    end
    -----------------------------------------------
    /*********************************[کنترل میزان بدهکار و بستانکار با ماهیت سرفصل]**********************/
    -----------------------------------------------
    set @jambed=0
    set @jambes=0
    declare @prevbed nvarchar , @prevbes nvarchar
    set @prevbed=@jambed
    set @prevbes=@jambes
    set @jambed=@jambed + @bed
    set @jambes=@jambes+@bes
    ---------کنترل با ماهیت-----------------
    if @mahiat=3
    begin
    if @jambed < @jambes
    begin
    raiserror('سرفصل بستانکار می شود مشخصات سرفصل کد کل : @a \n و کدمعین : @b \n و کد تفضیلی : @c \n و کد جز : @d \n جمع بدهکار : @e \n و جمع بستانکار : @f',1,1,@kolCode,@moinCode,@tafCode,@jozCode,@prev bed,@prevBes)
    goto done
    end
    end
    if @mahiat=4
    begin
    if @jambed > @jambes
    begin
    raiserror('سرفصل بدهکار می شود مشخصات سرفصل کد کل : @a \n و کدمعین : @b \n و کد تفضیلی : @c \n و کد جز : @d \n جمع بدهکار : @e \n و جمع بستانکار : @f',1,1,@kolCode,@moinCode,@tafCode,@jozCode,@prev bed,@prevBes)
    goto done
    end
    end
    ----------------------------------آپدیت جمع بد و بس سرفصل ها-------------------
    update utblSarfasl set jamBed=@jambed , jamBes=@jambes where SarfaslSN=@sarfaslId
    set @Error=@@ERROR
    if @Error<>0
    begin
    goto done
    end

    /*------------------------------------ذخیره آرتیکل ها----------------------------*/
    insert into utblGardeshSanad (SanadID,SarfaslID,GardeshSharh,GardeshBed,Gardesh Bes,InsertDate,InsertUser,TarikheBarge,ShomareBarg e)
    values
    (@sanadID,@SarfaslID,@sharh,@bed,@bes,GETDATE(),@I nsertUser,null,null)

    set @Error=@@ERROR
    if @Error<>0
    begin
    goto done
    end

    set @i=@i+1
    end
    ------------end of loop1
    commit tran tran1


    done:
    rollback tran tran1

  5. #5
    کاربر دائمی آواتار ozzy_mra
    تاریخ عضویت
    مهر 1388
    محل زندگی
    تهران
    پست
    544

    نقل قول: commit کردن موقت transaction

    برای استفاده از sp بالا من تو sql یه type تعریف کردم به شکل زیر
    CREATE TYPE [dbo].[artikleInfo] AS TABLE(
    [id] [int] NOT NULL,
    [koleKode] [nvarchar](200) NULL,
    [moinKode] [nvarchar](200) NULL,
    [tafKode] [nvarchar](200) NULL,
    [jozKode] [nvarchar](200) NULL,
    [sharhArt] [nvarchar](1000) NULL,
    [bedArt] [bigint] NULL,
    [BesArt] [bigint] NULL,
    PRIMARY KEY CLUSTERED
    (
    [id] ASC
    )WITH (IGNORE_DUP_KEY = OFF)
    )
    GO

    و دیتا تیبلم رو به این sp پاس میدم با این کد :

    using (SqlCommand command = newSqlCommand())
    {
    command.Connection = _conhelp;
    command.CommandType =
    CommandType.StoredProcedure;
    command.CommandText =
    "insertArticle";
    SqlParameter param = command.Parameters.AddWithValue("@articles", dtTemp);
    param.SqlDbType =
    SqlDbType.Structured;
    param.TypeName =
    "dbo.artikleInfo";
    command.Parameters.AddWithValue(
    "@articles", dtTemp);
    command.Parameters.AddWithValue(
    "@InsertUser", Convert.ToDouble(user) + ostan * .001);
    command.Parameters.AddWithValue(
    "@sanadID", sanadid);
    command.ExecuteNonQuery();
    }

    ولی نسبت به اطلاعاتی که به پروسیجرم پاس دادم کاری انجام نمی ده
    آخرین ویرایش به وسیله ozzy_mra : پنج شنبه 01 دی 1390 در 23:36 عصر

  6. #6
    کاربر دائمی آواتار ozzy_mra
    تاریخ عضویت
    مهر 1388
    محل زندگی
    تهران
    پست
    544

    نقل قول: commit کردن موقت transaction

    مشکلم با تعریف یک isolationLevel برای Transaction حل شد چون تو یکی از تابع ها از جدولی می خوند که تراکنش کامیت نشده ای روی اون در حال اجرا بود که برای تابع با تعریف ReadUncommited به عنوان IsolationLevel مشکل حل شد

  7. #7

    نقل قول: commit کردن موقت transaction

    چرا commit رو بعد از اتمام حلقه انجام نمی دید؟

  8. #8
    کاربر دائمی آواتار ozzy_mra
    تاریخ عضویت
    مهر 1388
    محل زندگی
    تهران
    پست
    544

    نقل قول: commit کردن موقت transaction

    نقل قول نوشته شده توسط Arash_janusV3 مشاهده تاپیک
    چرا commit رو بعد از اتمام حلقه انجام نمی دید؟
    ساختار این برنامه اینجوری بود (که الان کمی ساختارشو تغییر دادم) که ابتدا یه سری فیلد باید تو حلقه ثبت بشه اگه ارور داد کل باید رکبک بشه اگر از جدول دیگه ای استفاده می کردم کد درست مار می کرد اما مشکل اینجا بود که از همون جدولی که در حلقه for و برای اولین بار آپدیت انجام میشه (که تراکنش چون حلقه به پایان نرسیده commit نشده) یه دیتایی خونده بشه و همین باعث می شد که برنامه هنگ کنه که با اضافه کردت کد پایین به اونجایی که می خواستم دیتا رو بخونم مشکلم حل شد :
    using (SqlTransaction tr = con.BeginTransaction(IsolationLevel.ReadUncommitte  d)

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •