PMDK libpmemobj 例程2 事务操作

  pmemobj中具有事务的操作,事务的意思是被指定的一系列的操作要么执行成功,要么就失败,其中某一步错误也是失败。所以可以通过状态转换来完成失败函数的资源回收。
  采用如下5个状态表示TX_BEGIN(pop)、TX_ONCOMMIT、TX_ONABORT 、TX_FINALLY、TX_END,并这5个状态之间的转换关系如下,可通过pmemobj_tx_abort()等函数强行跳转。

PMDK libpmemobj 例程2 事务操作_第1张图片

#include 
#include 
#include 

int main(int argc, const char *argv[])
{
    const char path[] = "/home/hostname/pmemobj_setjmp.003";

    PMEMobjpool *pop = pmemobj_create(path, setjmp_example, PMEMOBJ_MIN_POOL, 0666);
    if (pop == NULL) {
        perror(path);
        exit(1);
    }

    TX_BEGIN(pop) {
        printf("begin\n");
    } TX_ONCOMMIT {
        printf("oncommit\n");
    } TX_ONABORT {
        printf("onabort\n");
    } TX_FINALLY {
        printf("finally\n");
    } TX_END
    printf("end\n");
    printf("\n");

    TX_BEGIN(pop) {
        printf("begin\n");
        pmemobj_tx_abort(EINVAL);
    } TX_ONCOMMIT {
        printf("oncommit\n");
    } TX_ONABORT {
        printf("onabort\n");
    } TX_FINALLY {
        printf("finally\n");
    } TX_END
    printf("end\n");
    printf("\n");

    TX_BEGIN(pop) {
        printf("begini b\n");
        TX_BEGIN(pop) {
            printf("begin\n");
        } TX_ONCOMMIT {
            printf("oncommit\n");
        } TX_ONABORT {
            printf("onabort\n");
        } TX_FINALLY {
            printf("finally\n");
        } TX_END
        printf("end\n");
    } TX_END
    printf("end b\n");
    printf("\n");

    TX_BEGIN(pop) {
        printf("begin b\n");
        TX_BEGIN(pop) {
            printf("begin\n");
            pmemobj_tx_abort(EINVAL);
        } TX_ONCOMMIT {
            printf("oncommit\n");
        } TX_ONABORT {
            printf("onabort\n");
        } TX_FINALLY {
            printf("finally\n");
        } TX_END
        printf("end\n");
    } TX_END
    printf("end b\n");
    printf("\n");

    pmemobj_close(pop);
    return 0;
}

  运行结果如下,特别需要强调的是如果进入了TX_ONABORT,则就会跳到上一层TX_END处,并且特性需要主要多层事务嵌套的逻辑关系:

$ ./setjmp 
begin
oncommit
finally
end

begin
onabort
finally
end

begini b
begin
oncommit
finally
end
end b

begin b
begin
onabort
finally
end b

  以上说明的是事务逻辑,并不方便操作persist数据,可采用事务函数处理persist数据,如操作失败,操作会回滚:
pmemobj_tx_add_range(PMEMoid, offset, size) 将PMEMoid指针处,偏移offset个偏移量后,大小为size的空间,作为事务操作。
pmemobj_tx_add_range_direct(ptr, size) 将ptr指针处,size大小的空间,作为事务操作。

int *to_modify = &vectorp->x;
TX_BEGIN(pop) {
    pmemobj_tx_add_range(root, offsetof(struct vector, x), sizeof(int));
    vectorp->x = 5;

    pmemobj_tx_add_range(root, 0, sizeof (struct vector));
    vectorp->x = 5;
    vectorp->y = 10;
    vectorp->z = 15;

    pmemobj_tx_add_range_direct(to_modify, sizeof (int));
    *to_modify = 5;
} TX_END





你可能感兴趣的:(Persistent,Memory)