首页 > Berkeley DB XML, Ying Cai > Berkeley DB XML 多线程添加文档例子

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+"";
                        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();
        }

}
  1. 天门冬
    2010年3月3日09:54 | #1

    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. 蔡瀛
    2010年3月3日10:31 | #2

    @天门冬
    使用2.5版本的情况呢。出现死锁的问题,请参考这里解决死锁的问题:http://www.oracle.com/technology/documentation/berkeley-db/xml/gsg_xml_txn/java/lockingsubsystem.html#deadlockresolve

  3. 天门冬
    2010年3月16日15:08 | #3

    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)

  4. 蔡瀛
  5. 小王
    2010年4月14日13:45 | #5

    你好,我的DBXML如果出错了,运行程序无法打开了。有什么办法恢复里面的数据吗?

  6. 蔡瀛
    2010年4月15日13:14 | #6

    @小王
    你说的出错了是什么意思?无法用openContainer打开?错误提示是什么呢?

  7. 小王
    2010年4月16日09:24 | #7

    就是在打开环境的时候就报错误了。我里面的数据有什么办法恢复吗?
    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

  8. 蔡瀛
    2010年4月16日10:10 | #8

    http://www.oracle.com/technology/documentation/berkeley-db/db/gsg_txn/JAVA/logconfig.html#logregionsize

    你可能要增加log region的大小。数据应该没有问题, 可以用dbxml shell打开那个container文件看看,拷贝到另外一个目录打开,或者把环境的那些文件都删除掉。

  9. 天门冬
    2010年4月22日14:42 | #9

    蔡瀛,你好!
    请问下,在运行的时候会生成很多的log.0000000001-log.00000000**的一大堆文件。这些文件主要是做什么的?可以删除吗,或者会自动清理?

  10. 蔡瀛
    2010年4月26日13:01 | #10

    不能删除这些文件,他们是日志文件,具体的请参考《Getting Started with Berkeley DB XML Transaction Processing》的第二章。

  1. 本文目前尚无任何 trackbacks 和 pingbacks.
注意: 评论者允许使用'@user空格'的方式将自己的评论通知另外评论者。例如, ABC是本文的评论者之一,则使用'@ABC '(不包括单引号)将会自动将您的评论发送给ABC。使用'@all ',将会将评论发送给之前所有其它评论者。请务必注意user必须和评论者名相匹配(大小写一致)。
Դ