This is a migrated thread and some comments may be shown as answers.

Transaction Lock method

5 Answers 91 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
bin
Top achievements
Rank 1
bin asked on 08 May 2011, 11:36 AM
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:

5 Answers, 1 is accepted

Sort by
0
Jan Blessenohl
Telerik team
answered on 09 May 2011, 09:05 AM
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.
0
bin
Top achievements
Rank 1
answered on 10 May 2011, 09:25 AM
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



0
Jan Blessenohl
Telerik team
answered on 12 May 2011, 03:53 PM
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.
0
bin
Top achievements
Rank 1
answered on 13 May 2011, 11:48 PM
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
0
Jan Blessenohl
Telerik team
answered on 18 May 2011, 04:47 PM
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.
Tags
Development (API, general questions)
Asked by
bin
Top achievements
Rank 1
Answers by
Jan Blessenohl
Telerik team
bin
Top achievements
Rank 1
Share this question
or