Berkeley DB XML 多线程添加文档例子
2010年3月1日
import java.io.File;
import java.util.concurrent.CountDownLatch;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import com.sleepycat.db.LockDetectMode;
import com.sleepycat.dbxml.XmlContainer;
import com.sleepycat.dbxml.XmlContainerConfig;
import com.sleepycat.dbxml.XmlDocument;
import com.sleepycat.dbxml.XmlDocumentConfig;
import com.sleepycat.dbxml.XmlException;
import com.sleepycat.dbxml.XmlManager;
import com.sleepycat.dbxml.XmlManagerConfig;
import com.sleepycat.dbxml.XmlQueryContext;
import com.sleepycat.dbxml.XmlResults;
import com.sleepycat.dbxml.XmlTransaction;
import com.sleepycat.dbxml.XmlUpdateContext;
public class DbxmlThreads extends Thread {
public static XmlManager mgr = null;
public static String containerName = "test.dbxml";
public static Environment dbEnv = null;
private static XmlContainer cont = null;
static {
EnvironmentConfig envConf = new EnvironmentConfig();
envConf.setThreaded(true);
envConf.setAllowCreate(true);
envConf.setTransactional(true);
envConf.setInitializeCache(true);
envConf.setInitializeLocking(true);
envConf.setInitializeLogging(true);
envConf.setCacheSize(64 * 1024 * 1024);
envConf.setLockDetectMode(LockDetectMode.DEFAULT);
XmlManagerConfig xmlMgrConfig = new XmlManagerConfig();
xmlMgrConfig.setAdoptEnvironment(true);
File dbHome = new File(".");
try {
dbEnv = new Environment(dbHome, envConf);
mgr = new XmlManager(dbEnv, xmlMgrConfig);
// 创建XmlContainer
if(mgr.existsContainer(containerName)!=0)
mgr.removeContainer(containerName);
XmlContainerConfig containerConf = new XmlContainerConfig();
containerConf.setTransactional(true);
containerConf.setAllowCreate(true);
containerConf.setContainerType(XmlContainer.NodeContainer);
cont = mgr.openContainer(containerName, containerConf);
cont.setAutoIndexing(false);
} catch (Exception e) {
e.printStackTrace();
}
}
private String name;
private CountDownLatch doneSignal;
DbxmlThreads(String name, CountDownLatch doneSignal) {
this.name = name;
this.doneSignal = doneSignal;
}
public void run() {
XmlTransaction txn = null;
try {
String content = "<"+name+">I am "+name+""+name+">";
for (int i = 0; i < 100; i++) {
XmlDocumentConfig dc = new XmlDocumentConfig();
dc.setGenerateName(true);
System.out.println(name+" insert "+i);
txn = mgr.createTransaction();
XmlDocument doc = mgr.createDocument();
doc.setContent(content);
cont.putDocument(txn, doc, dc);
txn.commit();
}
} catch (XmlException e) {
System.out.println("insert error:" + e.getMessage());
} finally {
doneSignal.countDown();
}
}
public static void main(String[] args) throws Exception {
CountDownLatch doneSignal = new CountDownLatch(5);
DbxmlThreads threadA = new DbxmlThreads("A", doneSignal);
DbxmlThreads threadB = new DbxmlThreads("B", doneSignal);
DbxmlThreads threadC = new DbxmlThreads("C", doneSignal);
DbxmlThreads threadD = new DbxmlThreads("D", doneSignal);
DbxmlThreads threadE = new DbxmlThreads("E", doneSignal);
threadA.start();
threadB.start();
threadC.start();
threadD.start();
threadE.start();
doneSignal.await();
XmlQueryContext qc = mgr.createQueryContext();
String query = "collection('"+containerName+"')/A";
XmlResults res = mgr.query(query, qc);
System.out.println("The results size is: "+res.size());
res.delete();
cont.close();
mgr.close();
}
}
Hi,蔡瀛你好。
根据你上面的多线程例子解决了我大部分的问题。但在我测试时,如果把数据量调大,还是会存在DB_LOCK_DEADLOCK问题,只是大大减小了出现次数。如下大概出现了2次。
我用的Berkeley DB XML版本:2.4.16
我把你上面的例子,把for里面的调整成:for (int i = 0; i < 10000; i++)
在过程中还是会遇到:insert error:Error: Db::put: DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock
@天门冬
使用2.5版本的情况呢。出现死锁的问题,请参考这里解决死锁的问题:http://www.oracle.com/technology/documentation/berkeley-db/xml/gsg_xml_txn/java/lockingsubsystem.html#deadlockresolve
Hi,你好。又有个问题要麻烦你看下了。
我运行了一段时间后,出现了如下问题。我查看了Berkeley DB XML论坛,说可以用setLogRegionSize来增加大小。我试了好像没有用!
Logging region out of memory; you may need to increase its size
The log message is null.
com.sleepycat.dbxml.XmlException: Error: Not enough space, errcode = DATABASE_ERROR
at com.sleepycat.dbxml.dbxml_javaJNI.XmlManager_openContainer__SWIG_2(Native Method)
请参考这里如何使用setLogRegionSzie: http://www.oracle.com/technology/documentation/berkeley-db/db/gsg_txn/JAVA/logconfig.html#logregionsize
你好,我的DBXML如果出错了,运行程序无法打开了。有什么办法恢复里面的数据吗?
@小王
你说的出错了是什么意思?无法用openContainer打开?错误提示是什么呢?
就是在打开环境的时候就报错误了。我里面的数据有什么办法恢复吗?
Logging region out of memory; you may need to increase its size
The log message is null.
com.sleepycat.dbxml.XmlException: Error: Not enough space, errcode = DATABASE_ERROR
http://www.oracle.com/technology/documentation/berkeley-db/db/gsg_txn/JAVA/logconfig.html#logregionsize
你可能要增加log region的大小。数据应该没有问题, 可以用dbxml shell打开那个container文件看看,拷贝到另外一个目录打开,或者把环境的那些文件都删除掉。
蔡瀛,你好!
请问下,在运行的时候会生成很多的log.0000000001-log.00000000**的一大堆文件。这些文件主要是做什么的?可以删除吗,或者会自动清理?
不能删除这些文件,他们是日志文件,具体的请参考《Getting Started with Berkeley DB XML Transaction Processing》的第二章。