Bug #8259
Reduce the work done by PreselectQuery.coreFetch
0%
History
#1 Updated by Alexandru Lungu 3 months ago
Eduard detected recently that there is some work being done in PreselectQuery.coreFetch
regarding an extra fetch.
After some analysis, there is the following conditional that triggers an extra fetch (eventually from session cache):
// if we have an ID only, a cached DMO, or we are working with a temp-table, fetch // the current version of the record (dirty DMO copy excepted) boolean doFetch = (!fullRec || isResultSetCached() || !buffer.isTemporary()) && !dirtyCopy;
- If the record is not full, I think it is clear that we should fetch it from the session cache / database. This can be kept
- If the result-set is cached, I don't think there should be much worry. Why would it make a difference if the results are an in-memory
SimpleResults
or a serializedScrollingResults
- they can both become stale. This stale problem is already resolved before-hand. This can be removed - If the buffer is persistent, the only problem is in regard to the locking. However, is the whole
session.get
logic still needed? This does a session cache look-up to retrieve the same DMO we already have incoreFetch
.- The only problem may come when needing to upgrade lock - this can be handled specially.
- Another problem may be if the DMO is stale. This can also be handled directly inside
coreFetch
. - Otherwise, we may use the DMO we have from the results right away.
My whole concern here is that we do an extra session cache look-up for almost any record that comes into a PreselectQuery
buffer (from persistent database). I need to measure first how slow is this process. The rough idea is to replace that code with:
// if we have an ID only, a cached DMO, or we are working with a temp-table, fetch // the current version of the record (dirty DMO copy excepted) boolean doFetch = (!fullRec || updateLock || dmo.isStale()) && !dirtyCopy;
Mind that the temporary condition is implicitly negated by updateLock
and isStale
is a natural condition here anyway.
#2 Updated by Eduard Soltan 3 months ago
Alexandru Lungu wrote:
My whole concern here is that we do an extra session cache look-up for almost any record that comes into a
PreselectQuery
buffer (from persistent database). I need to measure first how slow is this process. The rough idea is to replace that code with:// if we have an ID only, a cached DMO, or we are working with a temp-table, fetch // the current version of the record (dirty DMO copy excepted) boolean doFetch = (!fullRec || updateLock || dmo.isStale()) && !dirtyCopy;
Mind that the temporary condition is implicitly negated byupdateLock
andisStale
is a natural condition here anyway.
I think that assignment for updateLock
should also be upadated, as another fetch from cache/database should happen only if updateLock
is EXCLUSIVE.
updateLock = (lt == LockType.EXCLUSIVE || lt == LockType.EXCLUSIVE_NO_WAIT);
#3 Updated by Alexandru Lungu 3 months ago
I wonder if NO-LOCK to SHARE-LOCK is considered an lock update.
#4 Updated by Eric Faulhaber 3 months ago
Alexandru Lungu wrote:
I wonder if NO-LOCK to SHARE-LOCK is considered an lock update.
It is. Any change in lock level (none/share/exclusive) is considered a lock update.
#5 Updated by Alexandru Lungu 3 months ago
Eduard, this basically means that the condition in #8259-2 is incorrect.
Please post here a cut-out to the problem you have now with the locking.
#6 Updated by Eduard Soltan 3 months ago
For now in we assign to updateLock
the following expression: updateLock = (lt != LockType.NONE);
.
I think that in order to see if a lock should be changed we should verify if the current lock on the record is different that that send as parameter. updateLock = (lt != compLock);
#7 Updated by Alexandru Lungu 3 months ago
Eduard Soltan wrote:
For now in we assign to
updateLock
the following expression:updateLock = (lt != LockType.NONE);
.I think that in order to see if a lock should be changed we should verify if the current lock on the record is different that that send as parameter.
updateLock = (lt != compLock);
Eduard, we need a more large overview of a case that is no working with the current implementation and requires updateLock = (lt != compLock);
. Can this be replicated with trunk or only with your changes.
#8 Updated by Eduard Soltan 3 months ago
Alexandru Lungu wrote:
Eduard Soltan wrote:
For now in we assign to
updateLock
the following expression:updateLock = (lt != LockType.NONE);
.I think that in order to see if a lock should be changed we should verify if the current lock on the record is different that that send as parameter.
updateLock = (lt != compLock);
Eduard, we need a more large overview of a case that is no working with the current implementation and requires
updateLock = (lt != compLock);
. Can this be replicated with trunk or only with your changes.
It only can be seen with changes in #7999.
In case of a for each book fields (isbn)
query, an select book.isbn from book
sql query is created. And on any of retrieve operation operation (first/last/next/prev), a record with just a field is retrieved from database. But in coreFetch, it enters in if (doFetch)
and persistance.load
loads the entire record.