Ticket #427 (closed defect: fixed)
BigdataSail#getReadOnlyConnection() race condition with concurrent commit
| Reported by: | thompsonbry | Owned by: | thompsonbry |
|---|---|---|---|
| Priority: | critical | Milestone: | |
| Component: | Bigdata SAIL | Version: | BIGDATA_RELEASE_1_0_2 |
| Keywords: | SAIL, RWStore | Cc: | cchaulk, martyncutcher, mrpersonick |
Description
When using the RWStore or a federation it is possible that BigdataSail#getReadOnlyConnection?() should return a read-only transaction for data which had already been recycled. The relevant code in BigdataSail? is:
public BigdataSailConnection getReadOnlyConnection() {
final long timestamp = database.getIndexManager().getLastCommitTime();
return getReadOnlyConnection(timestamp);
}
The problem is that the timestamp obtained by this method is not atomic with respect to the commit protocol. It is possible that a concurrent commit could advance the last commit time and potentially recycle data associated with the transaction returned to the caller. This situation should be quite rare as it depends on the mutual timing of the request for the read-only transaction and the commit and, in situations where there is a heavy concurrent query workload, the situation is not likely to arise as the concurrent queries would also serve to protect the commit time.
The fix is to change this method to use the symbolic constant ITx.READ_COMMITTED:
public BigdataSailConnection getReadOnlyConnection() {
return getReadOnlyConnection(ITx.READ_COMMITTED);
}
This issue exists in the 1.0.x branch and the TERMS_REFACTOR_BRANCH.