Skip to content

Conversation

@swznd
Copy link

@swznd swznd commented Dec 22, 2015

No description provided.

@swznd
Copy link
Author

swznd commented Dec 22, 2015

upps.. sorry it seems duplicate with #102

but with different style.

try {
    \QB::beginTransaction();
    \QB::table('table')->insert(['column' => 'data']);
    \QB::table('table_2')->insert(['column' => 'data']);
    \QB::commit();
} catch (\Exception $e) {
    \QB::rollback();
}

@acburdine
Copy link
Contributor

@swznd: wouldn't it be a better idea to use booleans instead of 0 and 1 to check if a transaction is active?

@swznd
Copy link
Author

swznd commented Dec 26, 2015

hmm, if using booleans, when we call commit in another function/module it will disturb the previous transaction, because it just check true or false, without knowing how much transaction has been started.

For example, we meet the condition like this:

\QB::transaction(function($qb) {
    $insertId = $qb->table('table')->insert(['column' => 'data']);

    $anotherId = anotherFunction($insertId);

    \QB::table('table_3')->where('another_id', $anotherId)->update(['column' => 'data']);
});

function anotherFunction($id) 
{
    try {
        \QB::beginTransaction();
        $insertId = \QB::table('table_another')->insert(['table_id' => $id, 'column' => 'data']);
        \QB::commit();
    } catch (\Exception $e) {
        \QB::rollback();
        throw $e;
    }

    return $insertId;
}

when commit / rollback in anotherFunction executed it will disturb the transaction outside, so the next query will not run inside transaction as expected.

for reference:
laravel/framework#1686
laravel/framework#1823

@mrcnpdlk
Copy link

I had similar problem.
Its my solution below (pseudocode):

function firstQuery(){
   $qb->table('table_1')->insert($data1).....
}
function secondQuery(){
   $qb->table('table_2')->update($data2).....
}
function thirdQuery(){
   $qb->table('table_3')->delete().....
}

Main class/function:

$inTransaction = $qb->pdo()->inTransaction();
try {
    if (!$inTransaction) {
        $qb->pdo()->beginTransaction();
    }
    firstQuery();
    secondQuery();
    thirdQuery();
    if (!$inTransaction) {
        $qb->pdo()->commit();
    }
} catch (Exception $e) {
    if (!$inTransaction) {
        $qb->pdo()->rollBack();
    }
}

Of course for all sub-function/methods and main function/method instance of $qb have to by the same - only one connection to DB. In each method we should check if we are in transaction, then we can stack and nest methods/functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants