isolation.serializable

Posts   
 
    
shekar
User
Posts: 327
Joined: 26-Mar-2010
# Posted on: 09-Dec-2010 05:22:33   

LLBLGEN 3.0 Oracle 10g

I just have a basic quetsion. Why does the use of isolation.serializable which is permitted in llblgen does not place locks on rows selected?

I used it like this based on Daelmo suggestion

nitOfWork2 uow = new UnitOfWork2(); // ... DataAccessAdapter adapter = new DataAccessAdapter(); adapter.StartTransaction(IsolationLevel.serializable, "TestTrx"); try { uow.Commit(adapter); } catch (Exception) { // manage error }

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 09-Dec-2010 08:20:47   

I'm not sure what your UoW is doing. Could you please describe or show a code snippet of what you add to the UoW.

shekar
User
Posts: 327
Joined: 26-Mar-2010
# Posted on: 09-Dec-2010 08:37:25   

Walaa wrote:

I'm not sure what your UoW is doing. Could you please describe or show a code snippet of what you add to the UoW.

Dear Walaa Here is my full save code

private void SaveData() { var adaptersmartcatrd = new DataAccessAdapter(); var unitofwork = new UnitOfWork2(); adaptersmartcatrd.StartTransaction(IsolationLevel.Serializable, "PrepaidCard"); try {

            const decimal Postpaiduse = 0;
            Int32 TransactionTypeId = 0;
            decimal Prepaidbalance = !string.IsNullOrEmpty(tbxamount.Text) ||
                                     tbxamount.Text == @"0".Trim()
                                         ? Convert.ToDecimal(tbxamount.Text)
                                         : 0;
            const decimal Depositamount = 100;
            SmartCardUserno = cmbuserno.Text;
            string[] Userno = SmartCardUserno.Split(' ');
            DataTable TransactionTypeDt = TransactionType.returnTransactionType();
            if (TransactionTypeDt.Rows.Count > 0)
            {
                TransactionTypeId =
                    Convert.ToInt32(TransactionTypeDt.Rows[0]["TransactiontypeId"]);
            }
            if (Prepaidbalance >= 100)
            {
                DataTable BillCounterDt = ClubCentricBISpecific.SmartCard.BillCounterSmartCard();
                int BillNo = Convert.ToInt32(BillCounterDt.Rows[0]["Billnumber"]);
                int BillCounterNo = Convert.ToInt32(BillCounterDt.Rows[0]["BillcounterId"]);
                BillNo = BillNo + 1;
                var billcounter = new BillcounterEntity();
                adaptersmartcatrd.FetchEntity(billcounter);
                billcounter.BillcounterId = BillCounterNo;
                billcounter.IsNew = false;
                billcounter.Billnumber = BillNo;
                unitofwork.AddForSave(billcounter, true);
                var SmartCard = new SmartcardEntity();
                SmartCard.Cardid = Convert.ToInt32(CardRandomID);
                SmartCard.Postpaiduse = Postpaiduse;
                SmartCard.Prepaidbalance = Prepaidbalance - Depositamount;
                SmartCard.Depositamount = Depositamount;
                SmartCard.Isprepaid = GlobalVariable.optionYes;
                SmartCard.Ispostandprepaid = GlobalVariable.optionNo;
                SmartCard.Createddate = ServerDateTime.getcurrentserverdatewithtime();
                SmartCard.CreateduserId = StandardMessage.loginuserid;
                SmartCard.EmployeeId = EmployeeId;
                SmartCard.Roomno = RoomId;
                SmartCard.AffiliatememberId = AffiliatememberId;
                SmartCard.MemberId = MemberId;
                SmartCard.CorporateId = CorporateId;
                SmartCard.AffiliateclubId = null;
                SmartCard.Userno = Userno[0].ToUpper();
                unitofwork.AddForSave(SmartCard, true);
                var receiptSmartCard = new ReceiptsmartcardEntity();
                receiptSmartCard.Cardid = Convert.ToInt32(CardRandomID);
                receiptSmartCard.TransactiontypeId = TransactionTypeId;
                receiptSmartCard.Receiptdate = ServerDateTime.getcurrentserverdatewithtime();
                receiptSmartCard.Receiptnumber = BillNo;
                receiptSmartCard.Previousbalance = 0;
                receiptSmartCard.Amount = Prepaidbalance >= 100
                                              ? Prepaidbalance - Depositamount
                                              : 0;
                receiptSmartCard.Createddate = ServerDateTime.getcurrentserverdatewithtime();
                receiptSmartCard.CreateduserId = StandardMessage.loginuserid;
                unitofwork.AddForSave(receiptSmartCard, true);
                unitofwork.Commit(adaptersmartcatrd);
                {
                    MessageBox.Show(StandardMessage.datasavesuccess);
                    DoRefresh();
                }
                flashLabel.Text = "";
            }
            else
            {
                flashLabel.Text = "Amount Should be > 100";
            }
        }
        catch (Exception ex)
        {
            GlobalErrorHandler.LogMessage(ex.Message + ex.StackTrace);
            MessageBox.Show(StandardMessage.datasavefailure);
            adaptersmartcatrd.Rollback();
            return;
        }
        finally
        {
            adaptersmartcatrd.CloseConnection();
            adaptersmartcatrd.Dispose();
        }
    }
Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 09-Dec-2010 08:50:29   

So basically the UoW does an UPDATE on BillCounter, an INSERT on SmartCard and another INSERT on ReceiptSmartCard.

So is your question why there is no lock placed on the updated row?

shekar
User
Posts: 327
Joined: 26-Mar-2010
# Posted on: 09-Dec-2010 08:53:52   

Walaa wrote:

So basically the UoW does an UPDATE on BillCounter, an INSERT on SmartCard and another INSERT on ReceiptSmartCard.

So is your question why there is no lock placed on the updated row?

Exactly Sir. why there is no lock placed on the updated row?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 09-Dec-2010 10:36:48   

I'm under the impression that Oracle uses Multi-Version Concurrency Control, and so it deosn't use ReadLocks even in SERIALIZABLE transactions.

ref: http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96590/adg08sql.htm (section: Referential Integrity and Serializable Transactions)

LLBLGen Pro doesn't force Locks, as that can hurt performance very easily.

To work around this you may implement some Concurrency Control.

shekar
User
Posts: 327
Joined: 26-Mar-2010
# Posted on: 09-Dec-2010 10:59:41   

Walaa wrote:

I'm under the impression that Oracle uses Multi-Version Concurrency Control, and so it deosn't use ReadLocks even in SERIALIZABLE transactions.

ref: http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96590/adg08sql.htm (section: Referential Integrity and Serializable Transactions)

LLBLGen Pro doesn't force Locks, as that can hurt performance very easily.

To work around this you may implement some Concurrency Control.

Fine. but since it is DB feature which provides syntax 'SELECT_____ FOR UPDATE", it is surprising that I cant implement this syntax in LLBLGEN

MTrinder
User
Posts: 1461
Joined: 08-Oct-2008
# Posted on: 09-Dec-2010 21:35:25   

Primarily I guess because it's an Oracle specific feature, and LLBLGen tries to be as database agnostic as possible. Also because optimistic concurrency can be implemented using the usual techniques (timestamps, row version numbers) etc it's really not needed - there are very few occasions where it is really necessary to manually lock a row - as Walaa said, it's a performance killer.

Matt