Results of Lazy Loading with different scenarios

We can say that for every scenario the bug data was fetched just after time1. It may be useful to consider whether the userLogged or status objects could be considered to be "Read Consistent" with respect to the bug(at time1).

In understanding this you should be able to decide when to use lazy loading and the potential for "Read Inconsistent" results.

loggedBy statusTitle
Scenario 1 Name at time 2 Title @time 4
Scenario 2 Name at time 1 Title @time 4
Scenario 3 Name at time 1 Title @time 1
Scenario 4 Name at time 1 Title @time 1

Log for Scenario 1

The loggedUser is lazy loaded and because we are in a READ_COMMITED Isolation level it does see the Update at time2. The status title is lazy loaded in its own transaction just after time4.

Neither loggedBy nor statusTitle could be considered "Read Consistent" wrt Bug. It didn't matter that loggedBy was fetched in the same transaction, it can still potentially be not "Read Consistent" wrt Bug.


Update set UserName[Name at time 5]  statusTitle[Title @time 5] at time [5]
 INFO: DataSourcePool [ora10] grow pool;  busy[1] size[1] max[25]
Update set UserName[Name at time 1]  statusTitle[Title @time 1] at time [1]
<sql summary='[app.data.Bug]'>
SELECT b.id, b.body, b.cretime, b.duplicate_of, b.fixed_version,... 
FROM b_bug b 
WHERE b.id = ? 
</sql>
Update set UserName[Name at time 2]  statusTitle[Title @time 2] at time [2]
<sql summary='[app.data.User]'>
SELECT u.id, u.cookie_login, u.cretime, u.email, u.error_count,...
FROM s_user u 
WHERE u.id = ? 
</sql>
Update set UserName[Name at time 3]  statusTitle[Title @time 3] at time [3]
Update set UserName[Name at time 4]  statusTitle[Title @time 4] at time [4]
<sql summary='[app.data.BugStatus]'>
SELECT s.code, s.title 
FROM b_bug_status s 
WHERE s.code = ? 
</sql>
-------------------------
loggedBy:    [Name at time 2] 
statusTitle: [Title @time 4] 


Log for Scenario 2

Its the same as Scenario 1 except that the loggedBy value is [Name at time 1] due to the transaction isolation level and the fact that the transaction started with the first query which occured just after time1.

loggedBy could be considered "Read Consistent" wrt Bug but statusTitle could not be.

Log for Scenario 3 & 4

The user logged and bug status are included in the fetch. The fetch occurs just after time1 and No lazy loading occurs. The transaction isolation level doesn't matter. Results the same.


Update set UserName[Name at time 5]  statusTitle[Title @time 5] at time [5]
 INFO: DataSourcePool [ora10] grow pool;  busy[1] size[1] max[25]
Update set UserName[Name at time 1]  statusTitle[Title @time 1] at time [1]
<sql summary='[app.data.Bug, status, userLogged]'>
SELECT b.id, b.body, b.cretime, b.duplicate_of, b.fixed_version,...
        , ss.code, ss.title, b.type_code, b.user_assigned_id
        , au.id, au.cookie_login, au.cretime, au.email, au.error_count,...
FROM b_bug b
JOIN b_bug_status ss ON b.status_code = ss.code 
LEFT OUTER JOIN s_user au ON b.user_logged_id = au.id  
WHERE b.id = ? 
</sql>
Update set UserName[Name at time 2]  statusTitle[Title @time 2] at time [2]
Update set UserName[Name at time 3]  statusTitle[Title @time 3] at time [3]
Update set UserName[Name at time 4]  statusTitle[Title @time 4] at time [4]
-------------------------
loggedBy:    [Name at time 1] 
statusTitle: [Title @time 1] 

Summary

If you are running at READ_COMMITTED Isolation level you can not guarantee that queries are "Read Consistent" with respect to each other. That is, it does not matter if you Lazy Load inside of a transaction or not you have the potential to see newly committed changes and this includes the scenario that the database row you are lazy loading has been deleted.

You could say that at READ_COMMITTED Isolation level you will lazy load the "Most Recent" data rather than "Read Consistent" data wrt the original query.

Given that many people will frequently use some sort of 'Inactive Status' rather than actually deleting data, I believe the issue of lazy loading a row that has been deleted is pretty managable for most people.

To guarantee "Read Consistency" of the data you need to use a higher Transaction Isolation level such as SERIALIZABLE or include all the data into a single query (And use a Database that supports Statement level read consistency).

The cost of using SERIALIZABLE Isolation level is potentially significant, and often you will be unable to predicate the exact data required to include in the original query.

As long as you understand that you are often getting the "Most Recent" data rather than "Read Consistent" data you should enjoy the benefits that lazy loading brings.

You could say that at READ_COMMITTED Isolation level you will lazy load the "Most Recent" data rather than "Read Consistent" data wrt the original query.

Introduction User Guide (pdf) Install/Configure Public JavaDoc Whitepapers
General Database Specific Byte Code Deployment Annotations Features
Top Bugs Top Enhancements
woResponse