Open Opiumtm opened 6 years ago
It is pretty obtuse. Even when I was at MS and had full access to the code it took me a while to figure it out, and now I forget. :) This is from memory. Maybe @michaelthorp can correct me if I'm wrong:
JetSetSessionContext
comes in to play. There are some 'gotcha's about just what value you can pass in to it. I think you can pass in something like &state
in a C program so that the database engine knows which 'context' is accessing this transaction. Again, there is some 'gotcha' here that I got wrong the first time that I used this API and it didn't work, but I can't remember what it was.JetSetSessionContext
prior to starting the first transaction? And that you have to call JetResetSessionContext
after committing/rolling back to level 0?Hope that helps slightly, and sorry that I couldn't be more definitive.
-martin
@machish As far as I have understood from this repository unit tests and from quite unclear documentation at MSDN (no information on managed ESENT page, but some incomplete information on unmanaged ESENT API page), it looks like JetSessionContext
can take any valid IntPtr
(-1 and null
are explicitly stated as invalid values). At least, it's advised to pass a pointer to (arbitrary) valid C++ object on heap as a session context pointer value. But I'm not sure if I completely understand the valid value rules (Pointer should have reference to the allocated virtual memory page? Or not?) and I don't know how it's apply to managed .NET memory (where objects could be freely moved to the new address by GC) as it was advised to pass a pointer to the unmanaged C++ object.
It might be that you have to call JetSetSessionContext prior to starting the first transaction? And that you have to call JetResetSessionContext after committing/rolling back to level 0?
Unmanaged Esent API documentation explicitly states that to successfully invoke JetSetSessionContext
, session shouldn't be in any transaction and context should be set before you start any transaction.
@michaelthorp any info on this question?
@Opiumtm - I can't find anywhere that the pointer is dereferenced, so I believe you would be fine even if GC ran (I don't think .NET GC updates pointers). If you wanted to be safe (especially if you are planning on using long-living contexts) you could allocate some context on the managed heap and then GC wouldn't touch it so your pointer would stay.
Normally esent sessions are bound to thread on which they're created. Any attempt to use session on different thread results in exception. Although there is an API method to temporarily bind session to different thread, so session could be used from such thread without exception.
But this particular feature is poorly documented.
The meaning of "context" argument is unexplained and there is nowhere to find a clear explanation what it really means and what should be used for the "context" value.