This question is locked. New answers and comments are not allowed.
Hello,
we have a lot of objects to delete which results in an long running Flush.
We are wondering if it is possible to do this in an own thread so that the main application is accessible during the deletion process of OpenAccess and the DB.
First thought was to run the Flush in a seperated worker thread - this didn't work and we are also wondering what happens about a concurrent Flush from the main thread in that time.
Another thought was about using a second object scope in an own thread to do the whole job including loading the objects to delete and deleting them in an own transaction. Here is the question what happens if both main and worker thread did load the objects and only one of them runs the deletion?
However, what best practice would you suggest?
Greetings,
Carsten
we have a lot of objects to delete which results in an long running Flush.
We are wondering if it is possible to do this in an own thread so that the main application is accessible during the deletion process of OpenAccess and the DB.
First thought was to run the Flush in a seperated worker thread - this didn't work and we are also wondering what happens about a concurrent Flush from the main thread in that time.
Another thought was about using a second object scope in an own thread to do the whole job including loading the objects to delete and deleting them in an own transaction. Here is the question what happens if both main and worker thread did load the objects and only one of them runs the deletion?
However, what best practice would you suggest?
Greetings,
Carsten
6 Answers, 1 is accepted
0
Hello Carsten,
You should avoid using the same scope or context in more than one thread. A background thread for deletion is a good way to keep the application running. You can create a list of IObjectId instances in your main thread and pass it to the background thread. In that case you do not have to load the objects again, you just call scope.Remove with your List<IObjectId>. In the main thread, if you execute a query, the objects are deleted from the db, the problem is only if you have the objects still in the first level cache. As I know you have RefreshOnTransactionBegin set to false. A good way in that case is to start with a fresh scope in the main thread.
Best wishes,
Jan Blessenohl
the Telerik team
You should avoid using the same scope or context in more than one thread. A background thread for deletion is a good way to keep the application running. You can create a list of IObjectId instances in your main thread and pass it to the background thread. In that case you do not have to load the objects again, you just call scope.Remove with your List<IObjectId>. In the main thread, if you execute a query, the objects are deleted from the db, the problem is only if you have the objects still in the first level cache. As I know you have RefreshOnTransactionBegin set to false. A good way in that case is to start with a fresh scope in the main thread.
Best wishes,
Jan Blessenohl
the Telerik team
Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
0
Carsten
Top achievements
Rank 2
answered on 14 Mar 2011, 09:56 AM
Hello Jan,
you are right. We have set RefreshOnTransactionBegin to false. But I think we cannot use a new scope in the main thread, because we have to reload all other objects and that is a lot of data.
What is happening with the objects in the first level cache? Is there an other way to remove them?
Let me explain, what we have tested in the last days.
All of our objects are ordered in an object tree. To avoid loading a whole subtree before it is deleted we mark all object in the subtree in the database using a CTE which is very fast. Then we get all ObjectIDs from the subtree and check which objects are already loaded and cut off all references. Then the objects are free to delete.
Then we load all objects marked for deletion in another objectscope in a different thread. Up to this point everything works in most cases,
but we run into an other problem. The objects to delete are loaded in random order, but that doesn't matter. The problem is, that the objects are initialized by InitializeTransients. This causes Read/Write Exceptions if a child object is deleted before its owner is delete.
The thing is that we do not need InitializeTransients in this usecase.
Is it possible to suppress the events in one on the ObjectScopes?
Greetings
Carsten
you are right. We have set RefreshOnTransactionBegin to false. But I think we cannot use a new scope in the main thread, because we have to reload all other objects and that is a lot of data.
What is happening with the objects in the first level cache? Is there an other way to remove them?
Let me explain, what we have tested in the last days.
All of our objects are ordered in an object tree. To avoid loading a whole subtree before it is deleted we mark all object in the subtree in the database using a CTE which is very fast. Then we get all ObjectIDs from the subtree and check which objects are already loaded and cut off all references. Then the objects are free to delete.
Then we load all objects marked for deletion in another objectscope in a different thread. Up to this point everything works in most cases,
but we run into an other problem. The objects to delete are loaded in random order, but that doesn't matter. The problem is, that the objects are initialized by InitializeTransients. This causes Read/Write Exceptions if a child object is deleted before its owner is delete.
The thing is that we do not need InitializeTransients in this usecase.
Is it possible to suppress the events in one on the ObjectScopes?
Greetings
Carsten
0
Hello Carsten,
We are loading the objects exactly to call the callbacks to give the user the chance to hook into the process. There is no way to supress them at the moment.
But if you delete the objects in the parallel scope anyway, please think about doing it with direct sql or a cleanup SP. The SP can return a list of ids of objects that you have deleted and you can use scope.cache.evict(new GuidIdentity(type, id)) to cleanup your main scope.
Kind regards,
Jan Blessenohl
the Telerik team
We are loading the objects exactly to call the callbacks to give the user the chance to hook into the process. There is no way to supress them at the moment.
But if you delete the objects in the parallel scope anyway, please think about doing it with direct sql or a cleanup SP. The SP can return a list of ids of objects that you have deleted and you can use scope.cache.evict(new GuidIdentity(type, id)) to cleanup your main scope.
Kind regards,
Jan Blessenohl
the Telerik team
Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
0
Carsten
Top achievements
Rank 2
answered on 22 Mar 2011, 10:58 AM
Hello Jan,
we have managed to suppress the callbacks by comparing the scopes belonging to the objects.
Removing objects from the firstlevel cache of the mainobjectscope is also working.
Now i have another question. I use a stored procedure to mark element for deletion in the database. the stored procedure is using an exrta column in one table which is created by OpenAccess. The column is not represented by a field in one of our persistent classes so OpenAccess is not creating this column and always tries to remove it.
Is it possible to add this column to the mappingfile?
Greetings
Carsten
we have managed to suppress the callbacks by comparing the scopes belonging to the objects.
Removing objects from the firstlevel cache of the mainobjectscope is also working.
Now i have another question. I use a stored procedure to mark element for deletion in the database. the stored procedure is using an exrta column in one table which is created by OpenAccess. The column is not represented by a field in one of our persistent classes so OpenAccess is not creating this column and always tries to remove it.
Is it possible to add this column to the mappingfile?
Greetings
Carsten
0
Hi Carsten,
That is not possible but if you use vschema.exe from command line you can add the
-checkExtraColumns-
argument and we will keep all columns that we do not know about.
Greetings,
Jan Blessenohl
the Telerik team
That is not possible but if you use vschema.exe from command line you can add the
-checkExtraColumns-
argument and we will keep all columns that we do not know about.
Greetings,
Jan Blessenohl
the Telerik team
0
Carsten
Top achievements
Rank 2
answered on 24 Mar 2011, 08:55 AM
Hello Jan,
than it is probably easier to put an unused flag in our baseclass to create a column.
If we use checkExtraColumns OpenAccess will never drop removed field from the database and there can be a lot of modified columns. :-)
Greetings
Carsten
than it is probably easier to put an unused flag in our baseclass to create a column.
If we use checkExtraColumns OpenAccess will never drop removed field from the database and there can be a lot of modified columns. :-)
Greetings
Carsten