MongoDB Java Driver中的写操作策略

【转】https://github.com/xbwen/xbwen.github.io/wiki/MongoDB-Java-Driver%E4%B8%AD%E7%9A%84%E5%86%99%E6%93%8D%E4%BD%9C%E7%AD%96%E7%95%A5
1、WriteConcern

当Java程序往MongoDB中写数据的时候,可以通过设置WriteConcern参数,来控制写操作策略。

WriteConcern是MongoDB Java Driver提供的一个类,它提供了若干常量,其中最常用的2个如下:

ACKNOWLEDGED——Java Driver会等待MongoDB Server确认写操作完成。

UNACKNOWLEDGED——Java Driver把写操作请求发往MongoDB Server,然后立刻返回,不管MongoDB Server是否执行了该写操作。

显然,通过ACKNOWLEDGED能知道写操作是否成功,但执行写入操作会比较耗时;UNACKNOWLEDGED写入速度会非常快,但无法知道写入是否成功。

2、全局默认配置

接下来,我们结合BuguMongo中的代码,看看WriteConcern在实际中是如何使用的。

MongoDB Java Driver默认使用ACKNOWLEDGED,这个默认值是在MongoClientOptions中定义的:

public class MongoClientOptions {
    …
    private WriteConcern writeConcern = WriteConcern.ACKNOWLEDGED;
    …
}

也就是说,MongoDB Java Driver默认所有的写操作都是需要确认再返回的。如果你要改变这个全局的配置,可以在建立BuguConnection连接的时候,赋值一个自定义的MongoClientOptions。例如:

MongoClientOptions myOptions = MongoClientOptions.builder().writeConcern(WriteConcern.UNACKNOWLEDGED).build();
BuguConnection conn = BuguConnection.getInstance();
conn.setOptions(myOptions);
conn.connect("192.168.0.100", 27017, "mydb", "username", "password");

3、BuguDao中的WriteConcern

然而,在一个项目中,使用同一个写入策略,是不太现实的。我们往往需要经常变换写入策略。别担心,BuguDao提供了setWriteConcern()方法,你可以针对不同的Collection设定不同的写入策略,而且可以随时改变。

如果不进行设置的话,BuguDao默认使用的是ACKNOWLEDGED。

我们可以进行一个比较实验,分别使用ACKNOWLEDGED和UNACKNOWLEDGED,往MongoDB中写入1万条数据,看看耗时相差多少。

@Entity
public class Foo extends SimpleEntity {

    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

}

实验1:

BuguDao dao = new BuguDao(Foo.class);
long begin = System.currentTimeMillis();
for(int i=0; i<10000; i++){
    Foo foo = new Foo();
    foo.setContent("abcdefg" + i);
    dao.save(foo);
}
long end = System.currentTimeMillis();
System.out.println(end - begin);

这里,我们不对WriteConcern进行设置,而是使用默认的ACKNOWLEDGED。代码执行3次,在我的笔记本电脑上,输出的结果分别是:

55007, 55503, 54066

实验2:

BuguDao dao = new BuguDao(Foo.class);
//设置WriteConcern为UNACKNOWLEDGED,而不是默认的ACKNOWLEDGED
dao.setWriteConcern(WriteConcern.UNACKNOWLEDGED);  
long begin = System.currentTimeMillis();
for(int i=0; i<10000; i++){
    Foo foo = new Foo();
    foo.setContent("abcdefg" + i);
    dao.save(foo);
}
long end = System.currentTimeMillis();
System.out.println(end - begin);

代码执行3次,在我的笔记本电脑上,输出的结果分别是:

1736, 2636, 1470

可以看出,写入的速度快了很多。

4、写操作的返回值

上面的实验中,我们忽略了dao.save(foo)的返回值。实际上,BuguDao中的所有写操作,返回值都是WriteResult,而不是void。例如:

public WriteResult save(T t)

如果你使用的WriteConcern是UNACKNOWLEDGED,那么WriteResult是没有任何用处的。但如果你使用的是ACKNOWLEDGED,那么可以从WriteResult中获得写操作的结果,例如:操作是否成功,总共写了多少条数据,等等。

你可能感兴趣的:(NoSQL)