NaciO

Logo Objects ile SQL transaction nasıl yönetilebilir?

  Tiger/Logo Object Designer (LOD)

Bir işlem için birden fazla data nesnesi kaydetmeliyim. Ancak bu data nesnelerinden herhangi biri kaydedilemezse diğer kayıtların da gerçekleşmemesi gerekmektedir. Bunu nasıl yönetebilirim?
 


uyarlama LogoObjects OpenTrans


NaciO

Onaylanmış Cevap

Logo Objects data nesnelerinin içerisinde transaction yönetimi vardır. Bir kayıtla ilgili bir problem yaşandığında bu kayıt ve bağlantılı kayıtları geri alınır(rollback). Örneğin Fatura aktarımında, fatura satırlarından herhangi birinde bir hata alındığında fatura, bağlantılı irsaliyesi, satırları ve ödeme hareketleri gibi bağlantılı bilgiler veritabanına gönderilmez ve böylece "fatura başlığı olmayan satırlar", "satırları olmayan faturalar" gibi veri bozulmalarına izin vermez.

Ancak bu sistem kayıt bazında çalışır. Yani, bir süreçte önce malzeme kartı ve akabinde bu malzeme kartı ile bir sipariş aktarımı gerçekleşecek ise malzeme kartı aktarımı kendi içerisinde bir "SQL transaction"a sipariş ise kendi içerisinde bir "SQL transaction"a sahip olur. Bu örneğe göre siparişte yaşanan bir sorundan dolayı sipariş veritabanına yazılamazsa malzeme kartının da silinmesi gerekebilir.

Bu durumu yönetebilmek için data nesnelerinin kendi içerisindeki transaction'ı kapatmak gerekir. Bu işlemi data nesnelerindeki OpenTrans özelliğini False set ederek yapabiliriz. Bunun yanı sıra transaction'ı dışarıdan yönetecek bir yapı da kurulmalıdır. Aksi halde kontrolsüz bir akış olacaktır.

Yukarıdaki senaryonun örnek kodu yaklaşık olarak aşağıdaki gibidir;

bool ok;
UnityObjects.Query Qry = Global.UnityApp.NewQuery();
Qry.Statement = "BEGIN TRANSACTION T1";
if (Qry.Execute())
{
    // Malzeme kartı ekleniyor
    UnityObjects.Data Itm = Global.UnityApp.NewDataObject(UnityObjects.DataObjectType.doMaterial);
    Itm.New();
    Itm.OpenTrans = false;
    Itm.DataFields.FieldByName("CARD_TYPE").Value = 1;
    Itm.DataFields.FieldByName("CODE").Value = "MALZEME.01x";
    Itm.DataFields.FieldByName("USEF_PURCHASING").Value = 1;
    Itm.DataFields.FieldByName("USEF_SALES").Value = 1;
    Itm.DataFields.FieldByName("USEF_MM").Value = 1;
    Itm.DataFields.FieldByName("UNITSET_CODE").Value = "05";
    Itm.DataFields.FieldByName("SELVAT").Value = 18;
    Itm.DataFields.FieldByName("RETURNVAT").Value = 18;

    ok = Itm.Post();

    if (ok)
    {
        // Sipariş fişi ekleniyor
        UnityObjects.Data OrderSlip = Global.UnityApp.NewDataObject(UnityObjects.DataObjectType.doSalesOrderSlip);
        OrderSlip.New();
        Itm.OpenTrans = false;
        OrderSlip.DataFields.FieldByName("NUMBER").Value = "~";
        OrderSlip.DataFields.FieldByName("DATE").Value = "17.05.2015";
        OrderSlip.DataFields.FieldByName("TIME").Value = "09:29";
        OrderSlip.DataFields.FieldByName("ARP_CODE").Value = "CARI.01";
        OrderSlip.DataFields.FieldByName("ORDER_STATUS").Value = 1;
        OrderSlip.DataFields.FieldByName("CURRSEL_TOTAL").Value = 1;
        OrderSlip.DataFields.FieldByName("CURR_TRANSACTIN").Value = 20;

        UnityObjects.Lines OrderLine = OrderSlip.DataFields.FieldByName("TRANSACTIONS").Lines;
        OrderLine.AppendLine();
        OrderLine[OrderLine.Count - 1].FieldByName("TYPE").Value = 0;
        OrderLine[OrderLine.Count - 1].FieldByName("MASTER_CODE").Value = "MALZEME.01x";
        OrderLine[OrderLine.Count - 1].FieldByName("QUANTITY").Value = 30;
        OrderLine[OrderLine.Count - 1].FieldByName("PRICE").Value = 1000;
        OrderLine[OrderLine.Count - 1].FieldByName("VAT_RATE").Value = 18;
        OrderLine[OrderLine.Count - 1].FieldByName("UNIT_CODE").Value = "ADET";
        OrderLine[OrderLine.Count - 1].FieldByName("UNIT_CONV1").Value = 1;
        OrderLine[OrderLine.Count - 1].FieldByName("UNIT_CONV2").Value = 1;
        OrderLine[OrderLine.Count - 1].FieldByName("CURR_PRICE").Value = 160;

        ok = OrderSlip.Post();

        if (!ok) LOData.ErrorControl(OrderSlip);
    }
    else
    {
        LOData.ErrorControl(Itm);
    }

    // Eğer işlemler başarılı ise Commit ,
    // değilse RollBack komutu çalıştırılıyor
    if (ok)
    {
        Qry.Statement = "COMMIT TRANSACTION T1";
        if (!Qry.Execute()) MessageBox.Show(Qry.DBErrorDesc.ToString());
    }
    else
    {
        Qry.Statement = "ROLLBACK TRANSACTION T1";
        if (!Qry.Execute()) MessageBox.Show(Qry.DBErrorDesc.ToString());
    }
           
}
else
{
    MessageBox.Show(Qry.DBErrorDesc.ToString());
}
Qry.Close();

 


22/05/15 11:42


NaciO

Bir önceki örnekte adı geçen ErrorControl prosedürünün içeriği aşağıdaki gibidir.

public static void ErrorControl(UnityObjects.Data doData)
{
    if (doData.ErrorCode != 0)
    {
        MessageBox.Show(doData.ErrorCode.ToString() 
            + " : " 
            + doData.ErrorDesc.ToString() + "\n" 
            + doData.DBErrorDesc.ToString());
    }
    else
    {
        string txt = "XML Errors \n";
        for (int i = 0; i < doData.ValidateErrors.Count; i++)
        {
            txt = txt + doData.ValidateErrors[i].ID.ToString() 
                + " : " 
                + doData.ValidateErrors[i].Error.ToString() 
                + "\n";
        }
        MessageBox.Show(txt);
    }
}

 


22/05/15 13:23

Cevap vermek için giriş yapmanız gerekmektedir.