Click here to Skip to main content
15,885,695 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
hi i have searched alooooot for last 4 days..i have read allll the questions and articles and evry thing .. but i cant figure it out
my question is :
i have an mfc application connected to a sql server database via odbc
i want to lock a row when im editing it
its easy in many ereas .. even there is a fuction defined in crecordset named
setclockmode
that can has optimistic or pessimistic input parametere.. my ideal is that this function do the work for me with oessimistic parametere.. but when i run the app it says that my driver doesnt support pessimistic locking mode
and i have read that few odbc drivers support that(and i have no idea what does it mean!)
so..
i should lock the row..
i have tried the function executesql function i have tried transactions .. but yet cant understand what is my way .. and how they work..
here is my handler function on edit button:
C#
void CPhoneView::OnBnClickededitcurrent()
{
    //changing locking mode
    //SQLSetPos()

    //SQLSetStmtAttr(m_hstmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER)SQL_CONCUR_LOCK, SQL_IS_INTEGER);
    // ... execute query, bind data buffers
    //SQLFetchScroll(m_hstmt, SQL_FETCH_FIRST, 1); // move to row i want to modify (locks record)
    // ... update data buffers with modified data
    //SQLSetPos(m_hstmt, 1, SQL_UPDATE, SQL_LOCK_NO_CHANGE); // to save record


    //m_pSet->SetLockingMode(0);        //in afxdb.h header file there is enum lock mode that has defined the enumerations

    //m_pSet->m_pDatabase->ExecuteSQL(_T("SET TRANSACTION ISOLATION LEVEL READ SERIALIZABLE"));

    if (m_pSet->m_pDatabase->BeginTrans())
    {
        //try
        //{
        if (m_pSet->CanUpdate() && !m_pSet->IsDeleted())
        {
            m_pSet->Edit();                     // Allow the user to edit the current record
            UpdateData(true);                   // Perform all data exchange, updating the fields in the recordset          //if the change was suppose to be done by app,here
            if (MessageBox(_T("are you sure that you want to edit this record?"), _T("Attention:"), MB_YESNO | MB_ICONQUESTION) == IDYES)
            {
                if (m_pSet->Update())               // Save the user's changes to the current record
                    MessageBox(_T("Row Edited\n"), _T("done:"), MB_ICONASTERISK);

                else
                    MessageBox(_T("Row Cant be Edited\nor u didnt change any field to edit"), _T("Warning:"), MB_ICONWARNING);
            }
            else
            {
                m_pSet->CancelUpdate();
                MessageBox(_T("Row Not Edited\n"), _T("done:"), MB_ICONASTERISK);
            }
        }   // end if CanAppend(}
        m_pSet->m_pDatabase->CommitTrans();
    }
    //}
    /*CATCH_ALL(e)
    {
        !m_pSet->m_database.rollback();
        return false;
    }
    END_CATCH_ALL*/
        //return true;


    /*
    SQLSetStmtAttr(m_hstmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER)SQL_CONCUR_LOCK, SQL_IS_INTEGER);
    // ... execute query, bind data buffers
    SQLFetchScroll(m_hstmt, SQL_FETCH_FIRST, 1); // move to row i want to modify (locks record)
    // ... update data buffers with modified data
    SQLSetPos(m_hstmt, 1, SQL_UPDATE, SQL_LOCK_NO_CHANGE); // to save record */
}



plzz help me to get rid of this terrible headache:(
Posted

1 solution

that's not really how SQL is designed, SQL will only lock the row/page when you start the update transaction - if you want to mark a row 'out of bounds' for editing, you'll have to implement your own lock mechanism ... perhaps a nullable datetime column on each row, which marks that row as being edited (datetime so you can expire zombie'd row locks)

Failing that you'll have to implement a read/compare/update transaction that spots when the update is trying to change stale data, and fail, alerting the user
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900