Transaction Lock method

6 posts, 0 answers
  1. bin
    bin avatar
    11 posts
    Member since:
    Jun 2010

    Posted 08 May 2011 Link to this post

    Hi Sir,

    I used the following code to update a set of regions and in the same time no one can have read access to them

    IQueryable<Region> result = from q in objScope.Extent<Region>() select q;
                List<Region> list = result.ToList();
                objScope.TransactionProperties.Concurrency = TransactionMode.PESSIMISTIC_EXPLICIT;
                objScope.Transaction.Lock(list, LockMode.READ);
                objScope.Transaction.Begin();
                list[0].RegionDescription = "Eastern";
                blprovider.CommitTransaction();

    I got the following exception :

    Telerik.OpenAccess.Exceptions.InvalidOperationException was unhandled
      Message=The supplied instance is not of type Telerik.OpenAccess.SPI.dataobjects.PersistenceCapable (System.Collections.Generic.List`1[[Entity.Region, Entity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]). Are you trying to add a wrong object or is the assembly not enhanced?
      Source=Telerik.OpenAccess.Runtime
      CanRetry=true
      StackTrace:
           at OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.checkPersCapable(Object o)
           at OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.pmPreCheck(Object pc)
           at OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.retrieveImp(Object o, FetchPlanIF fPlan, RetrieveFetchContext rContext)
           at OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.retrieveAllImp(Object[] objects, Boolean useFetchPlan)
           at OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.retrieve(Object o, Boolean useFetchPlan)
           at OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.retrieve(Object o)
           at OpenAccessRuntime.DataObjects.SynchronizedPMProxy.retrieve(Object o)
           at Telerik.OpenAccess.RT.TransactionImpl.Lock(Object target, LockMode lm)
       .............
        ........... paths to local folders
    ................
           at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException: System.InvalidCastException
           Message=Specified cast is not valid.
           InnerException:
  2. Jan Blessenohl
    Admin
    Jan Blessenohl avatar
    707 posts

    Posted 09 May 2011 Link to this post

    Hi bin,
    PerstsinceCapable is the interface all your persistent classes get from the enhancer.

    You cannot pass in a list but only single persistent objects. You have to call lock inside the txn boundary, please move the call behind the begin.

    Regards,
    Jan Blessenohl
    the Telerik team
    Q1’11 SP1 of Telerik OpenAccess is available for download; also available is the Q2'11 Roadmap for Telerik OpenAccess ORM.
  3. DevCraft banner
  4. bin
    bin avatar
    11 posts
    Member since:
    Jun 2010

    Posted 10 May 2011 Link to this post

    Hi Sir,
    I modified my code as you told me before. As multiple threads sharing the same ObjectScope is not supported in OpenAccess, the  GetNewObjectScope method returns a new objectscope object for each thread. I used the following code in  multiple threads to increase the RegionID by one and to achieve this i have to set a lock read access on the last record in the region table then after i add a new Region i commit the transaction.

    private void ThreadOperation()
           {
               IObjectScope objectScope = GetNewObjectScope();
               objScope.TransactionProperties.Concurrency = TransactionMode.PESSIMISTIC_EXPLICIT;
               objScope.Transaction.Begin();
               Region r = (from q in objScope.Extent<Region>() select q).Last();
               objScope.Transaction.Lock(r, LockMode.READ);
               Region region = new Region();
               region.RegionID = r.RegionID + 1;
               region.RegionDescription = r.RegionDescription + r.RegionID.ToString();
               objScope.Add(region);
               objScope.Transaction.Commit();
           }

    I got the following exception :

    EXCEPTION : Telerik.OpenAccess.RT.sql.SQLException: Violation of PRIMARY KEY constraint 'PK_Region'. Cannot insert duplicate key in object 'dbo.Region'. The duplicate key value is (13). The statement has been terminated. at Telerik.OpenAccess.RT.Adonet2Generic.Impl.PreparedStatementImp.execute() at OpenAccessRuntime.Relational.conn.PooledPreparedStatement.execute() at OpenAccessRuntime.Relational.RelationalStorageManager.generateInserts(NewObjectOID oid, Int32 index, ClassMetaData cmd, PersistGraph graph, Int32[] fieldNos, CharBuf s, Object[] oidData, IntArray toUpdateIndexes)

    could you till me please how can i do it ???

    Thanks



  5. Jan Blessenohl
    Admin
    Jan Blessenohl avatar
    707 posts

    Posted 12 May 2011 Link to this post

    Hello bin,
    First, you cannot be sure that the query.Last returns the object with the highest id, please add an order by to have a fix ordering.
    Second why can't you use the autoinc or highlow key generator functionality instead of doing it by yourself?

    Kind regards,
    Jan Blessenohl
    the Telerik team
    Q1’11 SP1 of Telerik OpenAccess is available for download; also available is the Q2'11 Roadmap for Telerik OpenAccess ORM.
  6. bin
    bin avatar
    11 posts
    Member since:
    Jun 2010

    Posted 13 May 2011 Link to this post

    Hi Sir,
    I did all what you told me to do and I added the recursive method CheckID  to ensure that I am getting the last ID and i got the same error .

    private void ThreadOperation()
           {
               IObjectScope objectScope = GetNewObjectScope();
               objScope.TransactionProperties.Concurrency = TransactionMode.PESSIMISTIC_EXPLICIT;
               objScope.Transaction.Begin();
               Region r = (from q in objScope.Extent<Region>().OrderBy(t => t.RegionID) select q).Last();
               objScope.Transaction.Lock(r, LockMode.READ);
               Region region = new Region();
               region.RegionID = CheckID(r.RegionID);
               region.RegionDescription = r.RegionDescription + r.RegionID.ToString();
               objScope.Add(region);
               objScope.Transaction.Commit();
           }

           private int CheckID(int ID)
           {
               IObjectScope objectScope = GetNewObjectScope();
               Entity.Region r = (from q in objScope.Extent<Region>().Where(t => t.RegionID == ID) select q).FirstOrDefault();
               if (r != null)
               {
                   ID += 1;
                   CheckID(ID);
               }
               return ID;
           }

    I changed the LockMode to LockMode.WRITE  and i also got the same error.
    What is the autoinc or highlow key generator functionality ? how can i use it ???

    Thanks
  7. Jan Blessenohl
    Admin
    Jan Blessenohl avatar
    707 posts

    Posted 18 May 2011 Link to this post

    Hello bin,
    The problem is that if you want the last object, maybe you get the one before if the last is locked. I have attached a project showing autoinc and highlow behavior.

    Greetings,
    Jan Blessenohl
    the Telerik team
    Q1’11 SP1 of Telerik OpenAccess is available for download; also available is the Q2'11 Roadmap for Telerik OpenAccess ORM.
Back to Top
DevCraft banner