Hi,
I am using jackrabbit 1.5.6 with MSSQL as my persistence manager and
FileDataStore.
When more than one thread tries to add content to the same versionable
node, I am getting ItemNotFoundException.
The code responsible for add version is under concurrent lock.
Let me explain the inherent problem --
Let us consider the current base version is v1, there are threads t1 and
t2 which are trying to add version to v1.
first t1 gets the base version v1 and obtains the lock and adds version
and the current base version becomes v2 and releases the lock.
then t2 obtains the same lock and attempts to get the current base
version(which is v2) but it is getting v1 only and try to add the
version, but on checkout it is resulting in itemNotFoundException.
Is it because of the latency to update the data in DB or some thing.
Please find the piece of code attached.
BR,
Sunil Dhage
/*
* Adds a Versioned candidate photo node existing candidate node.
*/
private Node addVersionedPhotoContent(Session session) throws
IOException,RepositoryException
{ Lock nodelock = null;
Node photocontent = null;
LCCandidateContentType candidateContent =
(LCCandidateContentType)parameterMap.get("content");
ContentMetadataType contentMetadata =
candidateContent.getContentMetadata();
String accountID = String.valueOf(candidateContent.getAccountId());
String candidateID = candidateContent.getCandidateId();
String regID = String.valueOf(candidateContent.getRegistrationId());
log.info("Adding a new photo version for account-id ["+accountID+"] and
candidate-id ["+candidateID+"] ");
log.debug("Checking out the photo-content-node");
log.info("[add-new-photo-version] Acquiring the reentrantlock...");
try
{ RawContent contentResult = candidateContent.getRawContent();
InputStream in = contentResult.getContent().getInputStream();
String mimeType = contentResult.getMimeType();
log.info("mime type is :"+mimeType);
//Node photocontent =
candidatephoto.addNode(JcrConstants.JCR_CONTENT,JcrConstants.NT_RESOURCE);
nodelock =
locksMap.get(ContentConstants.LC_CANDIDATEPHOTOCONTENT_PATH);
nodelock.lock();
String path =
getNodePath(contentpath.getProperty(ContentConstants.LC_CANDIDATEPHOTOCONTENT_PATH),new
Object[]{accountID,candidateID,regID});
photocontent = validateNode(session,path);
photocontent.checkout();
photocontent.setProperty(JcrConstants.JCR_MIMETYPE, mimeType);
photocontent.setProperty(JcrConstants.JCR_DATA, in);
photocontent.setProperty(ContentConstants.LC_ATTRIB_ISACTIVE,contentMetadata.isActive());
Map<String,String> dynamicData =
contentMetadata.getAdditionalData();
String testCenterName =
dynamicData.get(LCDynamicDataKeys.TEST_CENTER_NAME);
String systemName = dynamicData.get(LCDynamicDataKeys.SYSTEM_NAME);
if (StringUtils.isNotBlank(testCenterName)) {
log.debug("Adding
"+ContentConstants.LC_ATTRIB_TEST_CENTER_NAME+" attribute with value :
"+testCenterName);
photocontent.setProperty(ContentConstants.LC_ATTRIB_TEST_CENTER_NAME,
testCenterName);
}
if (StringUtils.isNotBlank(systemName)) {
log.debug("Adding "+ContentConstants.LC_ATTRIB_SYSTEM_NAME+"
attribute with value : "+systemName);
photocontent.setProperty(ContentConstants.LC_ATTRIB_SYSTEM_NAME,
systemName);
}
Calendar lastModified = Calendar.getInstance();
Date createdDate =
candidateContent.getContentMetadata().getCreatedOn();
if (createdDate == null) {
lastModified.setTimeInMillis(System.currentTimeMillis());
} else {
lastModified.setTimeInMillis(createdDate.getTime());
}
log.info("[add-new-photo-version] Specifying last-modified time to
current time "+lastModified.getTime());
photocontent.setProperty(JcrConstants.JCR_LASTMODIFIED,
lastModified);
photocontent.setProperty(ContentConstants.LC_ATTRIB_RESOURCE_CREATEDON,
lastModified);
IOUtils.closeQuietly(in);
log.debug("Checking in the photo-content-node");
session.save();
photocontent = photocontent.checkin();
}catch(RepositoryException repex)
{ log.error("Error saving photo-content on
accountID["+accountID+"],candidateID["+candidateID+"], and
registerationID["+regID+"]");
throw repex;
}finally
{ if(nodelock!=null) nodelock.unlock();
}
return photocontent;
}