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

Speeding up deletion performance

6 Answers 81 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.
Carsten
Top achievements
Rank 2
Carsten asked on 22 Feb 2011, 04:54 PM
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

6 Answers, 1 is accepted

Sort by
0
Jan Blessenohl
Telerik team
answered on 22 Feb 2011, 06:23 PM
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
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
0
Jan Blessenohl
Telerik team
answered on 14 Mar 2011, 12:16 PM
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
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
0
Jan Blessenohl
Telerik team
answered on 22 Mar 2011, 11:59 AM
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
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
Tags
Development (API, general questions)
Asked by
Carsten
Top achievements
Rank 2
Answers by
Jan Blessenohl
Telerik team
Carsten
Top achievements
Rank 2
Share this question
or