storing entities out of a transaction scope

storing entities out of a transaction scope

a.kouchakzadeh
Advocate Advocate
832 Views
10 Replies
Message 1 of 11

storing entities out of a transaction scope

a.kouchakzadeh
Advocate
Advocate

Hello every one

I remember @_gile once told me about not keeping a database resident entity out of the scope of a transaction. it was long time ago and Im not even sure if it was an advise for a special condition or in general.

I have a couple of objectIds stored in an objectId collection. they are determined before a jig runs.

then since I cant use ed.SelectWindow(), @norman.yuan suggested to check if those entities are inside the window or not and mimic ed.SelectWindow() this way.

his idea works perfectly good. but my jig is too slow and I feel its most likely because of casting objects using transactions. so instead of casting object ids to entities, can I store a list of those entities?

for example, does this code cause any issues?

 

public class ListSpecialEntities
{
    public List<Entity> Result;
    public void GetSpecialEntities()
    {
        var doc = ACAD.DocumentManager.MdiActiveDocument;
        var ed = doc.Editor;
        var pso = new PromptSelectionOptions();
        pso.MessageForAdding = "Select some Entities";
        var sset = ed.GetSelection(pso);
        if(sset.Status==PromptStatus.OK)
        {
            using (var tr = doc.Database.TransactionManager.StartOpenCloseTransaction())
            {
                foreach(ObjectId id in sset.Value.GetObjectIds())
                {
                    Result.Add(tr.GetObject(id,OpenMode.ForRead) as Entity);
                }
            }
        }
    }
}

public class UseThoseEntities
{
    public ListSpecialEntities _ents;
    public UseThoseEntities(ListSpecialEntities lst)
    {
    _ents = lst;
    }
    public void ProcessThoseEntities()
    {
        foreach(Entity ent in _ents.Result)
        {
            //do some stuff
        }
    }
}

 

0 Likes
833 Views
10 Replies
Replies (10)
Message 2 of 11

_gile
Consultant
Consultant

What if you do all your stuff (selection, jig, ...) within the scope of a single transaction?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 11

a.kouchakzadeh
Advocate
Advocate

I cant because the class would be too complicated and chuncky. I have to do a fair amount of process before passing those entities to my jig class

0 Likes
Message 4 of 11

a.kouchakzadeh
Advocate
Advocate

or maybe you mean opening a transaction in the command class and passing it along with any other class that needs a transaction?

that might workout. but whats the problems caused if database entities are used out of the scope of a transaction?

0 Likes
Message 5 of 11

norman.yuan
Mentor
Mentor

If the said list of entities is only needed during a JIG's dragging operation, I do not see why it cannot be kept within a scope of a transaction, as @_gile suggested. It all comes to how you structure your code so that no matter how complicated the entities involved in the Jig are, the entire dragging is wrapped up inside a transaction, if the jig has to deal with DB-residing entities.

 

I can imagine that during the jig, when the mouse cursor moves, you may want to visualize different DB-residing entities, or even change/transform them, thus the repeated opening/closing. You could open them all at once when the jig begins.

 

Also, since the purpose of using JIG is to provide visual hints to the user who drags one or multiple entities, you could consider to use Transient graphics for the visual effects instead of having to open/close DB-residing entities repeatedly. This way, the actual DB-residing entities would not need to be changed/transformed during dragging and you only change them when the jig is Oked.

 

Based on your past posts, it might be possible that you may have overdone the jig operation when you say "I cant because the class would be too complicated and chuncky. I have to do a fair amount of process before passing those entities to my jig class".

 

It would be difficult to suggest anything without knowing exactly the details of the jig and its code.

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 6 of 11

ActivistInvestor
Mentor
Mentor

I mentioned to you quite some time back that what you are attempting to do in a jig is not feasible because of the amount of work that's happening in a jig that updates every time the mouse moves.

 

The reason your code is too slow to be feasible has absolutely nothing to do with having to open DBObjects. It is because your code doesn't bother to check  to see if the mouse has moved again, while it is doing all of that work (in which case, all of the work your code continues to do is for nothing, because the mouse has already moved again and each move of the mouse invalidates anything that you did at the previous cursor position). So, your code continues to do work to produce a result that is no-longer valid or needed, because the mouse has long since moved, possibly dozens of times.

 

Now, you seem to be trying to blame the fact that it is too slow on something other than your failing to do things the way they should be done.

 

See the last paragraph in this post.

 

0 Likes
Message 7 of 11

a.kouchakzadeh
Advocate
Advocate

If you mean returning SamplerStatus.NoChange when the mouse has not moved, my code does check if mouse has not moved and it returns NoChange.

>>On way to minimize lag while dragging is to use the Editor's MouseHasMoved property to short-circuit the update and/or drawing processes. if this property returns true, it means there are unprocessed mouse move events in the event queue and your update/drawing code should stop drawing and return immediately

is it possible to combine jig with Editor's mouse move event?

 

0 Likes
Message 8 of 11

a.kouchakzadeh
Advocate
Advocate

Im trying to figure out how to use transients instead of jig from the posts of your blog. does transient help reducing the amount of work comparing it with jig?

 

0 Likes
Message 9 of 11

ehsan_bahrani
Enthusiast
Enthusiast

Hi

To get object or open entity you need to do it inside a transaction but you can store them outside of transaction, if you want to read data/properties from entities, you can do it outside of transaction, but if you want to edit entities propertieses you need to do it inside a transaction.

 

If you want to create temporary entity that is not soppused to be used in the database, you can create it without any transaction.

 

Transactions just used to communicate with the database. So any thing that not relevant to database stuffs don't need a transaction and can be done outside of it. 

0 Likes
Message 10 of 11

ActivistInvestor
Mentor
Mentor

@a.kouchakzadeh wrote:

If you mean returning SamplerStatus.NoChange when the mouse has not moved, my code does check if mouse has not moved and it returns NoChange.


No, that's not what I mean. It is within your jig's Update() method (where the work is being done) that you should periodically check MouseHasMoved, and if it returns true, then immediately return from the method. For example, if you have a code loop inside of Update(), you might check MouseHasMoved within in loop iteration, and exit the loop and return if it returns true.

 

As it stands, your code performs the entire update operation even if the mouse has already moved before the operation has finished. If the mouse has already moved, there is no point to continuing to generate an obsolete drag representation, is there?

 


is it possible to combine jig with Editor's mouse move event?


You don't have to do that, you only have to check MouseHasMoved periodically from within the code that does the work inside your Update() method.

Message 11 of 11

a.kouchakzadeh
Advocate
Advocate

thanks to both Tony and Ehsan for the usefull info.

0 Likes