Aerospike提供在单个事务中对多个bin执行分开的单独修改操作的能力。此特性允许对同一条记录多个bin的修改与读取数据到客户端在单个事务中完成,即请允许应用执行原子性的修改且返回修改后的结果。
下面是可在一条记录上执行的操作列表。
操作 | 描述 | 条件 |
---|---|---|
write | 写入值到bin | |
read | 读取bin值 | |
increment | 增加一个bin的整型数值 | 必须是整型数值 |
append | 追加bin内容 | 追加内容的类型必须与bin原值的类型一致。数值类型只能是字节(bytes)或字符串(string) |
prepend | 前加bin内容 | 追加内容的类型必须与bin原值的类型一致。数值类型只能是字节(bytes)或字符串(string) |
touch | 更新修改记录的分代编号 |
下面是一个跟踪网站页面浏览数的应用举例。记录键是页面的URL,包含如下的bin:
地址、用户和时间bin都是以空字符(NULL)分割的字符串。地址、用户和时间是同步的,这样一个页面浏览相关的值在各个bin中是相同的索引位置。
as_operations ops; as_operations_inita(&ops, 5); as_operations_add_write_int64(&ops, "last-updated", timestamp); as_operations_add_incr(&ops, "views", 1); as_operations_add_append_raw(&ops, "addr", (uint8_t*)addr, strlen(addr) + 1); as_operations_add_append_raw(&ops, "user", (uint8_t*)user, strlen(user) + 1); as_operations_add_append_raw(&ops, "time", (uint8_t*)time, strlen(time) + 1); as_key key; as_key_init(&key, "app", "pages", url); if (aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec) != AEROSPIKE_OK) { fprintf(stderr, "err(%d) %s at [%s:%d]\n", err.code, err.message, err.file, err.line); } as_operations_destroy(&ops);
增加与读取是常见的操作顺序。允许应用使用一个计数器并在每次增加后读取值。
下面是一个页面浏览计数器。记录的键是URL,包含计数器的bin名称为“views”。
由于要执行读操作,所以需要提供一个记录对象用于填充读取的记录数值。
as_operations ops; as_operations_inita(&ops, 2); as_operations_add_incr(&ops, "views", 1); as_operations_add_read(&ops, "views"); as_record _rec; as_record *rec = as_record_inita(&_rec, 1); as_key key; as_key_init(&key, "app", "pages", url); if (aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec) != AEROSPIKE_OK) { fprintf(stderr, "err(%d) %s at [%s:%d]\n", err.code, err.message, err.file, err.line); } else { printf("views = %ld\n", as_record_get_int64(rec, "views", 0)); } as_record_destroy(rec); as_operations_destroy(&ops);
每条记录都包含元数据,比如:记录的分代编号(generation )和生存时间(TTL)。分代编号可被认为是记录的版本号,记录每次更新时会增加。生存时间是记录失效的到期时间。读取记录时,这些值都不会被修改。若一条记录的生存时间是5分钟,即使是不断地读取,5分钟过后它也不再可用。为了保证记录不失效,可使用touch操作。
下面的例子,读取3个bin并touch一条记录,使其不至失效。我们要从数据库中读取这些bin,所以初始化了一个容纳3个bin的记录对象。
as_operations ops; as_operations_inita(&ops, 4); as_operations_add_touch(&ops); as_operations_add_read(&ops, "x"); as_operations_add_read(&ops, "y"); as_operations_add_read(&ops, "z"); as_record _rec; as_record *rec = as_record_inita(&_rec, 3); as_key key; as_key_init(&key, "app", "pages", url); if (aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec) != AEROSPIKE_OK) { fprintf(stderr, "err(%d) %s at [%s:%d]\n", err.code, err.message, err.file, err.line); } else { printf("x = %ld\n", as_record_get_int64(rec, "x", 0)); printf("y = %ld\n", as_record_get_int64(rec, "y", 0)); printf("z = %ld\n", as_record_get_int64(rec, "z", 0)); } as_record_destroy(rec); as_operations_destroy(&ops);
请参见目录【examples/basic_examples/touch】下的更多使用aerospike_key_operate()的示例