iOS SQLite FMDB 事务..正确用法?

发布于 2024-11-18 18:03:01 字数 316 浏览 2 评论 0原文

我将尝试使用 FMDB SQLite iOS 包装器进行事务处理。

该文档对交易有点模糊,但通过快速查看一些函数,我得出了以下逻辑:

[fmdb beginTransaction];
    // Run the following query
    BOOL res1 = [fmdb executeUpdate:@"query1"];
    BOOL res2 = [fmdb executeUpdate:@"query2"];

if(!res1 || !res2) [fmdb rollback];
else [fmdb commit];

I'm just going to try out using transactions with the FMDB SQLite iOS wrapper.

The documentation is a little vague on transactions but from having a quick look at some functions I have come up with the following logic:

[fmdb beginTransaction];
    // Run the following query
    BOOL res1 = [fmdb executeUpdate:@"query1"];
    BOOL res2 = [fmdb executeUpdate:@"query2"];

if(!res1 || !res2) [fmdb rollback];
else [fmdb commit];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

溺深海 2024-11-25 18:03:01

您还可以使用 FMDatabaseQueue 来处理事务,它是 fmdb 的一部分:

[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];

    if (whoopsSomethingWrongHappened) {
        *rollback = YES;
        return;
    }
    // etc…
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
}];

文档< /a>

You could also use FMDatabaseQueue to handle your transactions, which is part of fmdb:

[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];

    if (whoopsSomethingWrongHappened) {
        *rollback = YES;
        return;
    }
    // etc…
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
}];

Documentation

迟月 2024-11-25 18:03:01

如果第一次更新失败,我不会尝试进行第二次更新。

bool ret = false;
[fmdb beginTransaction];
ret = [fmdb executeUpdate:@"query1"];
if (ret)
{
    ret = [fmdb executeUpdate:@"query2"];
    if (!ret)
    {
         // report error 2
    }
}

if(ret) 
{
    if (![fmdb commit])
    {
        // panic!
    }
}
else
{
    if (![fmdb rollback])
    {
        // panic!
    }
}

为了保持偏执的鲁棒性,你应该有一个 try ... catch 块,以防万一抛出异常。如果你这样做了,你就可以利用它来发挥你的优势。

[fmdb beginTransaction];
@try
{
    if (![fmdb executeUpdate:@"query1"])
    {
        // report error
        @throw someExcpetion;
    }
    if (![fmdb executeUpdate:@"query2"])
    {
        // report error
        @throw someExcpetion;
    }
    [fmdb commit]
}
@catch(NSException* e)
{
    [fmdb rollback];
    // rethrow if not one of the two exceptions above
}

I wouldn't try to do the second update if the first failed.

bool ret = false;
[fmdb beginTransaction];
ret = [fmdb executeUpdate:@"query1"];
if (ret)
{
    ret = [fmdb executeUpdate:@"query2"];
    if (!ret)
    {
         // report error 2
    }
}

if(ret) 
{
    if (![fmdb commit])
    {
        // panic!
    }
}
else
{
    if (![fmdb rollback])
    {
        // panic!
    }
}

For paranoid robustness you should have a try ... catch block in case anything throws an exception. If you do, you can use it to your advantage.

[fmdb beginTransaction];
@try
{
    if (![fmdb executeUpdate:@"query1"])
    {
        // report error
        @throw someExcpetion;
    }
    if (![fmdb executeUpdate:@"query2"])
    {
        // report error
        @throw someExcpetion;
    }
    [fmdb commit]
}
@catch(NSException* e)
{
    [fmdb rollback];
    // rethrow if not one of the two exceptions above
}
泅人 2024-11-25 18:03:01

快捷方式:

let queue = FMDatabaseQueue(path: databaseURL.path!)

queue.inTransaction() {
    db, rollback in

    result = db.executeUpdate("INSERT INTO client VALUES (NULL, ?)", client.name ?? "")

    if result {
        client.ID = Int(db.lastInsertRowId())
    } else {
        rollback.initialize(true)
        print("\(__FUNCTION__) insert into table failed: \(db.lastErrorMessage())")
    }
}

queue.close()

Swift way:

let queue = FMDatabaseQueue(path: databaseURL.path!)

queue.inTransaction() {
    db, rollback in

    result = db.executeUpdate("INSERT INTO client VALUES (NULL, ?)", client.name ?? "")

    if result {
        client.ID = Int(db.lastInsertRowId())
    } else {
        rollback.initialize(true)
        print("\(__FUNCTION__) insert into table failed: \(db.lastErrorMessage())")
    }
}

queue.close()
仅此而已 2024-11-25 18:03:01

这似乎是一个有效的使用场景,我可能会在执行回滚之前添加输出 -lastErrorMessage-lastErrorCode 的值,以便您了解什么完全错了。

更好的是,在每个 -executeUpdate 之后进行这些调用,这样您就知道每个语句之后是否发生了错误:

[fmdb beginTransaction];

// Run the following query
BOOL res1 = [fmdb executeUpdate:@"query1"];
if (!res1) {
   NSLog(@"Error %d - %@", [fmdb lastErrorMessage], [fmdb lastErrorCode]);
}

BOOL res2 = [fmdb executeUpdate:@"query2"];
if (!res2) {
   NSLog(@"Error %d - %@", [fmdb lastErrorMessage], [fmdb lastErrorCode]);
}

if(!res1 || !res2) [fmdb rollback];
else [fmdb commit];

It seems like a valid usage scenario, to which I might add outputting the values of -lastErrorMessage and -lastErrorCode before you perform a rollback, so that you get a sense of what exactly went wrong.

Better yet, make those calls after each -executeUpdate, so you'll know if an error occured after each statement:

[fmdb beginTransaction];

// Run the following query
BOOL res1 = [fmdb executeUpdate:@"query1"];
if (!res1) {
   NSLog(@"Error %d - %@", [fmdb lastErrorMessage], [fmdb lastErrorCode]);
}

BOOL res2 = [fmdb executeUpdate:@"query2"];
if (!res2) {
   NSLog(@"Error %d - %@", [fmdb lastErrorMessage], [fmdb lastErrorCode]);
}

if(!res1 || !res2) [fmdb rollback];
else [fmdb commit];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文