在计算机科学和数据库领域,事务是指作为一个不可分割的操作序列,要么全部执行,要么全部不执行的一组数据库操作。事务通常具有以下四个特性,即ACID:
Atomicity(原子性):事务中的所有操作要么全部执行成功,要么全部不执行,不会出现部分执行的情况。
Consistency(一致性):事务执行前后,数据库的状态必须保持一致,即事务执行后数据库从一个一致的状态转换到另一个一致的状态。
Isolation(隔离性):事务的执行不会受到其他事务的影响,即一个事务的执行过程中对其他事务是隔离的。
Durability(持久性):一旦事务提交,其结果应该是永久性的,即对数据库的影响是持久的。
在 ZooKeeper 中,没有直接提供 transaction() 方法来执行多个操作的原子性。但是,ZooKeeper 提供了 multi() 方法来实现原子性的多个操作。multi() 方法允许客户端将多个操作放在一个事务中,然后一次性提交给 ZooKeeper 服务器,这样可以确保这些操作要么全部成功,要么全部失败。
org.apache.zookeeper.Transaction transaction()
事务是 multi(java.lang.Iterable) 方法的精简封装,它提供了一个构建器对象,可用于构建和提交一组原子操作。
下面示例演示使用事务一次性常见多个节点和删除一个节点,代码如下:
package com.hxstrive.zookeeper;
import com.alibaba.fastjson.JSONObject;
import org.apache.zookeeper.*;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
/**
* zookeeper 事务操作
* @author hxstrive.com
*/
public class TransactionNode {
private static ZooKeeper zooKeeper;
@Before
public void init() throws Exception {
zooKeeper = new ZooKeeper("127.0.0.1:2181", 2000, new Watcher() {
public void process(WatchedEvent watchedEvent) {
System.out.println("触发了 " + watchedEvent.getType() + " 事件");
}
});
}
@Test
public void syncDemo() throws Exception {
// 开启事务
Transaction transaction = zooKeeper.transaction();
// 创建多个节点
zooKeeper.create("/trans_node", "new value".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zooKeeper.create("/trans_node/node1", "data1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zooKeeper.create("/trans_node/node2", "data2".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zooKeeper.create("/trans_node/node3", "data3".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
// 删除一个节点
zooKeeper.delete("/trans_node/node3", -1);
// 提交事务
List<OpResult> resultList = transaction.commit();
for(OpResult opResult : resultList) {
System.out.println("结果:" + JSONObject.toJSONString(opResult));
}
}
}当然,我们也可以直接使用带有参数的 List<org.apache.zookeeper.OpResult> multi(Iterable<org.apache.zookeeper.Op> ops) 方法替代。