Merged V3.2 to HEAD

17363: Fix to DbNodeServiceImple to allow restored nodes.
   17384: Minor comments
   17451: Fix ETHREEOH-2751 / ETWOONE-340 - specialising a node through an action doesn't set default values from model
   17459: ETHREEOH-2391 - Invite pending task now has lots of properties
   17465: Repo side fix for ETHREEOH-3010: Inbound and outbound Mltext multiple property are not converted correctly
   17478: Fix ETHREEOH-3340 - WCM - Revert to snapshot failure (fix AVM getListing -> AVNSync compare -> WCM revertSnapshot)
   17483: (record only) Merged V3.1 to V3.2 (record-only)
      17482: (record-only) due to earlier back-merge
   17493: Fix for ETHREEOH-3342: index.recovery.mode example is incorrect
   17494: Fix for ETHREEOH-3027: missingFullTextReindexTrigger (from index-recovery-context.xml) job does not work.
   17510: Fix for ETHREEOH-1147: Indexing large indices can lead to Java Heap space.
   17511: Fix for ETHREEOH-1271: It is possible to add one category more than one time to the same content or space
   17513: ETHREEOH_3366: Altered DictionaryDAOImpl so that passing a null QName into getType and getAspect does not result in an NPE
   17531: ETHREEOH-1186: Corrected rssfeed.get.js so a user can configure a RSS Feed dashlet that has been placed on their own dashboard
   17550: ETHREEOH-2317: Rule not fired when document has no content
   17556: Fixed ETHREEOH-1229: Can't delete space that contains "translation without content"
   17558: Fix for ETHREEOH-3356: Forms fail to persist if property or association name has an _ (underscore) in it
   17572: Changed caching of person NodeRefs so that duplicates are detected better
   17573: Fixed UTF-8 for file with encoded chars
   17576: LockAcquisitionException message specific to failed release of taken-over lock
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /alfresco/BRANCHES/V3.2:r17363,17384,17451,17459,17465,17478,17483,17493-17494,17510-17511,17513,17531,17550,17556,17558,17572-17573,17576


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18140 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2010-01-19 14:07:10 +00:00
parent 6b8cf8d13b
commit c67a5c18d2
28 changed files with 4343 additions and 3536 deletions

View File

@@ -87,15 +87,14 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
* @author andyh
*/
public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneIndexerAndSearcher, XAResource,
ApplicationContextAware
public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneIndexerAndSearcher, XAResource, ApplicationContextAware
{
private static Log logger = LogFactory.getLog(AbstractLuceneIndexerAndSearcherFactory.class);
private int queryMaxClauses;
private int indexerBatchSize;
protected Map<String, LuceneQueryLanguageSPI> queryLanguages = new HashMap<String, LuceneQueryLanguageSPI>();
/**
@@ -155,6 +154,12 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
private int maxDocsForInMemoryMerge = 10000;
private int maxDocsForInMemoryIndex = 10000;
private double maxRamInMbForInMemoryMerge = 16.0;
private double maxRamInMbForInMemoryIndex = 16.0;
private int maxDocumentCacheSize = 100;
private int maxIsCategoryCacheSize = -1;
@@ -172,8 +177,10 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
private int mergerMergeFactor = 5;
private int mergerMergeBlockingFactor = 1;
private int mergerMinMergeDocs = 1000;
private int mergerMaxBufferedDocs = IndexWriter.DISABLE_AUTO_FLUSH;
private double mergerRamBufferSizeMb = 16.0;
private int mergerTargetIndexCount = 5;
@@ -181,7 +188,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
private int mergerTargetOverlaysBlockingFactor = 1;
private int termIndexInterval =IndexWriter.DEFAULT_TERM_INDEX_INTERVAL;
private int termIndexInterval = IndexWriter.DEFAULT_TERM_INDEX_INTERVAL;
private boolean useNioMemoryMapping = true;
@@ -189,7 +196,9 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
private int writerMergeFactor = 5;
private int writerMinMergeDocs = 1000;
private int writerMaxBufferedDocs = IndexWriter.DISABLE_AUTO_FLUSH;
private double writerRamBufferSizeMb = 16.0;
private boolean cacheEnabled = true;
@@ -206,7 +215,6 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
super();
}
/*
* (non-Javadoc)
* @seeorg.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.
@@ -219,6 +227,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
/*
* (non-Javadoc)
*
* @see org.alfresco.repo.search.impl.lucene.LuceneConfig#getApplicationContext()
*/
public ConfigurableApplicationContext getApplicationContext()
@@ -404,7 +413,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
if (indexers == null)
{
indexers = new HashMap<StoreRef, LuceneIndexer>();
AlfrescoTransactionSupport.bindResource(indexersKey, indexers);
AlfrescoTransactionSupport.bindResource(indexersKey, indexers);
}
LuceneIndexer indexer = indexers.get(storeRef);
if (indexer == null)
@@ -431,8 +440,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
}
else if (TransactionSynchronizationManager.isSynchronizationActive())
{
Map<StoreRef, LuceneIndexer> indexers = (Map<StoreRef, LuceneIndexer>) AlfrescoTransactionSupport
.getResource(indexersKey);
Map<StoreRef, LuceneIndexer> indexers = (Map<StoreRef, LuceneIndexer>) AlfrescoTransactionSupport.getResource(indexersKey);
if (indexers != null)
{
LuceneIndexer indexer = indexers.get(storeRef);
@@ -474,7 +482,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
LuceneSearcher searcher = getSearcher(storeRef, indexer);
return searcher;
}
/**
* Get node-based searcher (for "selectNodes / selectProperties")
*/
@@ -776,7 +784,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
if (indexers != null)
{
indexers.clear();
AlfrescoTransactionSupport.unbindResource(indexersKey);
AlfrescoTransactionSupport.unbindResource(indexersKey);
}
}
}
@@ -1031,7 +1039,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
*
* @author Derek Hulley
*/
public static class LuceneIndexBackupComponent /*implements InitializingBean*/
public static class LuceneIndexBackupComponent /* implements InitializingBean */
{
ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
@@ -1590,7 +1598,6 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
defaultMLSearchAnalysisMode = mode;
}
public int getMaxDocIdCacheSize()
{
return maxDocIdCacheSize;
@@ -1690,7 +1697,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
{
this.mergerMergeFactor = mergerMergeFactor;
}
public int getMergerMergeBlockingFactor()
{
return mergerMergeBlockingFactor;
@@ -1701,14 +1708,14 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
this.mergerMergeBlockingFactor = mergerMergeBlockingFactor;
}
public int getMergerMinMergeDocs()
public int getMergerMaxBufferedDocs()
{
return mergerMinMergeDocs;
return mergerMaxBufferedDocs;
}
public void setMergerMinMergeDocs(int mergerMinMergeDocs)
public void setMergerMaxBufferedDocs(int mergerMaxBufferedDocs)
{
this.mergerMinMergeDocs = mergerMinMergeDocs;
this.mergerMaxBufferedDocs = mergerMaxBufferedDocs;
}
public int getMergerTargetIndexCount()
@@ -1730,7 +1737,7 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
{
this.mergerTargetOverlayCount = mergerTargetOverlayCount;
}
public int getMergerTargetOverlaysBlockingFactor()
{
return mergerTargetOverlaysBlockingFactor;
@@ -1781,14 +1788,14 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
this.writerMergeFactor = writerMergeFactor;
}
public int getWriterMinMergeDocs()
public int getWriterMaxBufferedDocs()
{
return writerMinMergeDocs;
return writerMaxBufferedDocs;
}
public void setWriterMinMergeDocs(int writerMinMergeDocs)
public void setWriterMaxBufferedDocs(int writerMaxBufferedDocs)
{
this.writerMinMergeDocs = writerMinMergeDocs;
this.writerMaxBufferedDocs = writerMaxBufferedDocs;
}
public boolean isCacheEnabled()
@@ -1800,29 +1807,112 @@ public abstract class AbstractLuceneIndexerAndSearcherFactory implements LuceneI
{
this.cacheEnabled = cacheEnabled;
}
public boolean getPostSortDateTime()
{
return postSortDateTime;
}
public void setPostSortDateTime(boolean postSortDateTime)
{
this.postSortDateTime = postSortDateTime;
return postSortDateTime;
}
public void setPostSortDateTime(boolean postSortDateTime)
{
this.postSortDateTime = postSortDateTime;
}
public void registerQueryLanguage(LuceneQueryLanguageSPI queryLanguage)
{
this.queryLanguages.put(queryLanguage.getName().toLowerCase(), queryLanguage);
}
/**
* @return the maxDocsForInMemoryIndex
*/
public int getMaxDocsForInMemoryIndex()
{
return maxDocsForInMemoryIndex;
}
/**
* @param maxDocsForInMemoryIndex
* the maxDocsForInMemoryIndex to set
*/
public void setMaxDocsForInMemoryIndex(int maxDocsForInMemoryIndex)
{
this.maxDocsForInMemoryIndex = maxDocsForInMemoryIndex;
}
/**
* @return the maxRamInMbForInMemoryMerge
*/
public double getMaxRamInMbForInMemoryMerge()
{
return maxRamInMbForInMemoryMerge;
}
/**
* @param maxRamInMbForInMemoryMerge
* the maxRamInMbForInMemoryMerge to set
*/
public void setMaxRamInMbForInMemoryMerge(double maxRamInMbForInMemoryMerge)
{
this.maxRamInMbForInMemoryMerge = maxRamInMbForInMemoryMerge;
}
/**
* @return the maxRamInMbForInMemoryIndex
*/
public double getMaxRamInMbForInMemoryIndex()
{
return maxRamInMbForInMemoryIndex;
}
/**
* @param maxRamInMbForInMemoryIndex
* the maxRamInMbForInMemoryIndex to set
*/
public void setMaxRamInMbForInMemoryIndex(double maxRamInMbForInMemoryIndex)
{
this.maxRamInMbForInMemoryIndex = maxRamInMbForInMemoryIndex;
}
/**
* @return the mergerRamBufferSizeMb
*/
public double getMergerRamBufferSizeMb()
{
return mergerRamBufferSizeMb;
}
/**
* @param mergerRamBufferSizeMb
* the mergerRamBufferSizeMb to set
*/
public void setMergerRamBufferSizeMb(double mergerRamBufferSizeMb)
{
this.mergerRamBufferSizeMb = mergerRamBufferSizeMb;
}
/**
* @return the writerRamBufferSizeMb
*/
public double getWriterRamBufferSizeMb()
{
return writerRamBufferSizeMb;
}
/**
* @param writerRamBufferSizeMb
* the writerRamBufferSizeMb to set
*/
public void setWriterRamBufferSizeMb(double writerRamBufferSizeMb)
{
this.writerRamBufferSizeMb = writerRamBufferSizeMb;
}
protected LuceneQueryLanguageSPI getQueryLanguage(String name)
{
return this.queryLanguages.get(name);
}
protected abstract List<StoreRef> getAllStores();
public <R> R doWithAllWriteLocks(WithAllWriteLocksWork<R> lockWork)

View File

@@ -110,7 +110,7 @@ public interface LuceneConfig
* Lucene writer config
* @return
*/
public int getWriterMinMergeDocs();
public int getWriterMaxBufferedDocs();
/**
* Lucene writer config
@@ -128,7 +128,7 @@ public interface LuceneConfig
* Lucene merger config
* @return
*/
public int getMergerMinMergeDocs();
public int getMergerMaxBufferedDocs();
/**
* Lucene merger config
@@ -244,4 +244,34 @@ public interface LuceneConfig
*/
public ConfigurableApplicationContext getApplicationContext();
/**
* Ram based limit for in memory merges
* @return
*/
public double getMaxRamInMbForInMemoryMerge();
/**
* Ram based limit for in memory portion of writer index.
* @return
*/
public double getWriterRamBufferSizeMb();
/**
* Ram based limit for in memory portion of merger index.
* @return
*/
public double getMergerRamBufferSizeMb();
/**
* Max docs to allow for in memory indexes (does no apply to merges)
* @return
*/
public int getMaxDocsForInMemoryIndex();
/**
* Max Ram to allow for in memory indexes (does not apply to merges)
* @return
*/
public double getMaxRamInMbForInMemoryIndex();
}

View File

@@ -74,6 +74,7 @@ import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.GUID;
import org.alfresco.util.TraceableThreadFactory;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.Analyzer;
@@ -99,6 +100,7 @@ import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.store.RAMDirectory;
import org.apache.xml.dtm.ref.sax2dtm.SAX2DTM2.FollowingSiblingIterator;
import org.safehaus.uuid.UUID;
import org.saxpath.SAXPathException;
import org.springframework.context.ApplicationContext;
@@ -229,7 +231,7 @@ public class IndexInfo implements IndexMonitor
* Lock for the index entries
*/
private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
/**
* Read only index readers that also do reference counting.
*/
@@ -295,14 +297,22 @@ public class IndexInfo implements IndexMonitor
*/
private static HashMap<File, IndexInfo> indexInfos = new HashMap<File, IndexInfo>();
// Properties that cotrol lucene indexing
// Properties that control lucene indexing
// --------------------------------------
// Properties for indexes that are created by transactions ...
private int maxDocsForInMemoryMerge = 10000;
private int maxDocsForInMemoryIndex = 10000;
private int writerMinMergeDocs = 1000;
private double maxRamInMbForInMemoryMerge = 16.0;
private double maxRamInMbForInMemoryIndex = 16.0;
private int writerMaxBufferedDocs = IndexWriter.DISABLE_AUTO_FLUSH;
private double writerRamBufferSizeMb = 16.0;
private int writerMergeFactor = 5;
@@ -312,7 +322,9 @@ public class IndexInfo implements IndexMonitor
// Properties for indexes created by merging
private int mergerMinMergeDocs = 1000;
private int mergerMaxBufferedDocs = IndexWriter.DISABLE_AUTO_FLUSH;
private double mergerRamBufferSizeMb = 16.0;
private int mergerMergeFactor = 5;
@@ -404,10 +416,15 @@ public class IndexInfo implements IndexMonitor
this.threadPoolExecutor = config.getThreadPoolExecutor();
IndexInfo.useNIOMemoryMapping = config.getUseNioMemoryMapping();
this.maxDocsForInMemoryMerge = config.getMaxDocsForInMemoryMerge();
this.writerMinMergeDocs = config.getWriterMinMergeDocs();
this.maxRamInMbForInMemoryMerge = config.getMaxRamInMbForInMemoryMerge();
this.maxDocsForInMemoryIndex = config.getMaxDocsForInMemoryIndex();
this.maxRamInMbForInMemoryIndex = config.getMaxRamInMbForInMemoryIndex();
this.writerMaxBufferedDocs = config.getWriterMaxBufferedDocs();
this.writerRamBufferSizeMb = config.getWriterRamBufferSizeMb();
this.writerMergeFactor = config.getWriterMergeFactor();
this.writerMaxMergeDocs = config.getWriterMaxMergeDocs();
this.mergerMinMergeDocs = config.getMergerMinMergeDocs();
this.mergerMaxBufferedDocs = config.getMergerMaxBufferedDocs();
this.mergerRamBufferSizeMb = config.getMergerRamBufferSizeMb();
this.mergerMergeFactor = config.getMergerMergeFactor();
this.mergerMergeBlockingFactor = config.getMergerMergeBlockingFactor();
this.mergerMaxMergeDocs = config.getMergerMaxMergeDocs();
@@ -464,7 +481,8 @@ public class IndexInfo implements IndexMonitor
{
writer = new IndexWriter(emptyIndex, new AlfrescoStandardAnalyser(), true, MaxFieldLength.LIMITED);
writer.setUseCompoundFile(writerUseCompoundFile);
writer.setMaxBufferedDocs(writerMinMergeDocs);
writer.setMaxBufferedDocs(writerMaxBufferedDocs);
writer.setRAMBufferSizeMB(writerRamBufferSizeMb);
writer.setMergeFactor(writerMergeFactor);
writer.setMaxMergeDocs(writerMaxMergeDocs);
writer.setWriteLockTimeout(writeLockTimeout);
@@ -531,7 +549,8 @@ public class IndexInfo implements IndexMonitor
{
writer = new IndexWriter(oldIndex, new AlfrescoStandardAnalyser(), false, MaxFieldLength.LIMITED);
writer.setUseCompoundFile(writerUseCompoundFile);
writer.setMaxBufferedDocs(writerMinMergeDocs);
writer.setMaxBufferedDocs(writerMaxBufferedDocs);
writer.setRAMBufferSizeMB(writerRamBufferSizeMb);
writer.setMergeFactor(writerMergeFactor);
writer.setMaxMergeDocs(writerMaxMergeDocs);
writer.setWriteLockTimeout(writeLockTimeout);
@@ -821,7 +840,7 @@ public class IndexInfo implements IndexMonitor
{
indexEntries.put(id, new IndexEntry(IndexType.DELTA, id, "", TransactionStatus.ACTIVE, "", 0, 0, false));
}
}
finally
{ // Downgrade lock
@@ -858,7 +877,8 @@ public class IndexInfo implements IndexMonitor
writer = new IndexWriter(location, analyzer, false, MaxFieldLength.LIMITED);
}
writer.setUseCompoundFile(writerUseCompoundFile);
writer.setMaxBufferedDocs(writerMinMergeDocs);
writer.setMaxBufferedDocs(writerMaxBufferedDocs);
writer.setRAMBufferSizeMB(writerRamBufferSizeMb);
writer.setMergeFactor(writerMergeFactor);
writer.setMaxMergeDocs(writerMaxMergeDocs);
writer.setWriteLockTimeout(writeLockTimeout);
@@ -1081,7 +1101,7 @@ public class IndexInfo implements IndexMonitor
getWriteLock();
try
{
mainIndexReader = null;
mainIndexReader = null;
}
finally
{
@@ -1116,7 +1136,7 @@ public class IndexInfo implements IndexMonitor
mainIndexReader = createMainIndexReader();
}
}
finally
{
@@ -1128,17 +1148,18 @@ public class IndexInfo implements IndexMonitor
mainIndexReader.incRef();
if (s_logger.isDebugEnabled())
{
s_logger.debug("Main index reader references = " + ((ReferenceCounting)mainIndexReader).getReferenceCount());
s_logger.debug("Main index reader references = " + ((ReferenceCounting) mainIndexReader).getReferenceCount());
}
// Prevent close calls from really closing the main reader
return new FilterIndexReader(mainIndexReader) {
return new FilterIndexReader(mainIndexReader)
{
@Override
protected void doClose() throws IOException
{
in.decRef();
}
}
};
}
@@ -1239,11 +1260,12 @@ public class IndexInfo implements IndexMonitor
filterReader.decRef();
}
// The reference count would have been incremented automatically by MultiReader / FilterIndexReaderByStringId
// The reference count would have been incremented automatically by MultiReader /
// FilterIndexReaderByStringId
deltaReader.decRef();
if (s_logger.isDebugEnabled())
{
s_logger.debug("Main index reader references = " + ((ReferenceCounting)mainIndexReader).getReferenceCount());
s_logger.debug("Main index reader references = " + ((ReferenceCounting) mainIndexReader).getReferenceCount());
}
reader = ReferenceCountingReadOnlyIndexReaderFactory.createReader(MAIN_READER + id, reader, false, config);
ReferenceCounting refCounting = (ReferenceCounting) reader;
@@ -1298,8 +1320,7 @@ public class IndexInfo implements IndexMonitor
}
getReadLock();
}
releaseReadLock();
getWriteLock();
try
@@ -1992,13 +2013,53 @@ public class IndexInfo implements IndexMonitor
referenceCountingReadOnlyIndexReaders.put(id, reader);
}
private double getSizeInMb(File file)
{
long size = getSize(file);
return size/1024.0d/1024.0d;
}
private long getSize(File file)
{
long size = 0l;
if (file == null)
{
return size;
}
if (file.isFile())
{
return file.length();
}
else
{
File[] files = file.listFiles();
if(files == null)
{
return size;
}
for (File current : files)
{
if (current.isDirectory())
{
size += getSize(current);
}
else
{
size += current.length();
}
}
}
return size;
}
private IndexReader buildReferenceCountingIndexReader(String id, long size) throws IOException
{
IndexReader reader;
File location = new File(indexDirectory, id).getCanonicalFile();
double folderSize = getSizeInMb(location);
if (IndexReader.indexExists(location))
{
if ((config != null) && (size < config.getMaxDocsForInMemoryMerge()))
if ((size < maxDocsForInMemoryIndex) && (folderSize < maxRamInMbForInMemoryIndex))
{
RAMDirectory rd = new RAMDirectory(location);
reader = IndexReader.open(rd);
@@ -2947,9 +3008,9 @@ public class IndexInfo implements IndexMonitor
private abstract class AbstractSchedulable implements Schedulable, Runnable
{
ScheduledState scheduledState = ScheduledState.UN_SCHEDULED;
private int scheduledCount;
public synchronized int getScheduledCount()
{
return scheduledCount;
@@ -3767,6 +3828,7 @@ public class IndexInfo implements IndexMonitor
IndexWriter writer = null;
File outputLocation = null;
double mergeSize = 0;
for (IndexEntry entry : toMerge.values())
{
File location = new File(indexDirectory, entry.getName()).getCanonicalFile();
@@ -3784,12 +3846,13 @@ public class IndexInfo implements IndexMonitor
}
readers[count++] = reader;
docCount += entry.getDocumentCount();
mergeSize += getSizeInMb(location);
}
else if (entry.getStatus() == TransactionStatus.MERGE_TARGET)
{
mergeTargetId = entry.getName();
outputLocation = location;
if (docCount < maxDocsForInMemoryMerge)
if ((docCount < maxDocsForInMemoryMerge) && (mergeSize < maxRamInMbForInMemoryMerge))
{
ramDirectory = new RAMDirectory();
writer = new IndexWriter(ramDirectory, new AlfrescoStandardAnalyser(), true, MaxFieldLength.UNLIMITED);
@@ -3800,7 +3863,8 @@ public class IndexInfo implements IndexMonitor
}
writer.setUseCompoundFile(mergerUseCompoundFile);
writer.setMaxBufferedDocs(mergerMinMergeDocs);
writer.setMaxBufferedDocs(mergerMaxBufferedDocs);
writer.setRAMBufferSizeMB(mergerRamBufferSizeMb);
writer.setMergeFactor(mergerMergeFactor);
writer.setMaxMergeDocs(mergerMaxMergeDocs);
writer.setWriteLockTimeout(writeLockTimeout);