java lucene 技术(3) : 锁机制
3.1锁机制
经典之作”Lucene in action”中,在涉及到lucene锁机制时,书中给出了一个案例,它告诉我们在不关闭前一个IndexWriter的情况下,不可以允许第二个IndexWriter对索引文件进行操作。笔者在对这个例子亲自测试之后,发现书中显示的报错信息只在Lucene 1.4.3 中出现,在Lucene2.1.0下,并没有出现,测试代码如下:
public class CreatLock {
private Directory dir;
protected void setUp() throws IOException{
String indexdir = System.getProperty("java.io.tempdir","tmp")+
System.getProperty("file.separator")+"index";
dir = FSDirectory.getDirectory(indexdir,true);
}
public void testWriteLock() throws IOException{
IndexWriter writer1= null;
IndexWriter writer2 = null;
try{
IndexWriter writer1= new IndexWriter(dir,new SimpleAnalyzer(), true);
IndexWriter writer2 = new IndexWriter(dir,new SimpleAnalyzer(),true);
System.out.println(“lucene 2.1.0 is ok”);
}
catch(IOException e){
System.out.println(e.getMessage());
}
}
Public static void main(String args[]){
CreatLock cl = new CreatLock();
cl.setUp();
cl. testWriteLock();
}
}
读者可以将此程序分别在Lucene 1.4.3 和Lucene2.1.0下测试,查看谁会产生书中的错误,感兴趣的读者可以查看两版本的IndexWriter源码,相信一定可以发现产生不同结果的原因是什么。
导致Lucene 1.4.3 下报错的凶手是临时目录下的生成了后缀为.lock的文件,如果不消除这个锁文件,就无法通过另一个IndexWriter对同一个索引文件操作;另外,通过其他高手的文章得知,通过JAVA序列化可以避免这个问题的发生,对此,我就不在此处详述了。
通过这个例子,我们可以了解到:Lucene在同一时刻对只允许执行单一进程的所有代码段中,Lucene都创建了基于文件的锁,以此来避免误用Lucene 的API造成对索引的损坏。既然提到了锁机制,就不得不提到Lucene并发性问题了。
3.2并发性
通过一个表格,看看Lucene的并发性规则吧。
操作 | 是否允许 |
对同一个索引运行多个并行的搜索进程 | 允许 |
对一个正在生成、被优化或正在与另一索引合并的索引运行多个并行的搜索进程,或该索引正在进行删除、更新文档等操作时,对索引运行多个并行的搜索进程 | 允许 |
对同一个索引用多个IndexWriter对象执行添加、更新文档的操作 | 不允许 |
当一个从索引中删除文档的IndexReader对象没有成功关闭时,打开一个IndexWriter对象用于在这个索引中添加新的文档 | 不允许 |
IndexWriter对象向索引中添加新文档后,未成功关闭;在此之后,打开一个IndexReader对象用于从这个索引中删除文档 | 不允许 |
为了避免对索引文件造成损坏,我们需要遵循这些特定的规则。这类问题通常会在web应用程序中突显出来。因为web应用程序是同时为多个请求而服务的。