Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transactions support #294

Merged
merged 85 commits into from
Jul 1, 2022
Merged

Transactions support #294

merged 85 commits into from
Jul 1, 2022

Conversation

ziaratban
Copy link
Contributor

@ziaratban ziaratban commented Jan 23, 2020

Q A
Is bugfix? no
New feature? yes
Breaks BC? no
Tests pass? yes

Examples

#Starts and commits transaction in easy mode 
yii::$app->mongodb->transaction(function($clientSession){
    #Your codes in transaction
},[
    'readConcern' => 'snapshot',
    'writeConcern' => 'majority',
]);
#Supports nested calling (this is not nested transaction!)
yii::$app->mongodb->transaction(function(){

    User::deleteAll(...);

    yii::$app->mongodb->transaction(function(){
        #Execute your mongodb commands in new session and transaction
        User::deleteAll(...);

        yii::$app->mongodb->noTransaction(function(){
             #Execute your mongodb commands in out of session and transaction
             //your codes ...
        });
    }); 

    return false; #Roll backing the current transaction
});
#Other way
yii::$app->mongodb->startTransaction([
    'readConcern' => 'snapshot', #transaction options
],[
    'causalConsistency' => true, #session options
]);

#your codes ...

yii::$app->mongodb->commitTransaction(); #or yii::$app->mongodb->rollBackTransaction();

Once feature
Starts and commits transaction in easy mode if the previous transaction was not executed, otherwise only runs your actions in previous transaction.

yii::$app->mongodb->transaction(function(){
    yii::$app->mongodb->transactionOnce(function(){
        #Execute your mongodb commands in previous transaction.
    });
});
yii::$app->mongodb->startSession(); #Ends the previous session and starts the new session.
yii::$app->mongodb->startSessionOnce(); #The session does not start.

Lock a document for update

yii::$app->mongodb->transaction(function($clientSession){
    #Locks a document of the collection in a transaction(like `select for update` feature in mysql)
    try{
        $doc = MyActiveRecordClass::LockDocument(new ObjectId('5e5fa6125845350caf596ed6'), '_lock');
        if($doc === null)
            echo 'document not found!';
        else{
            #The document is locked and you can have a safe update
        }
    }
    catch(\Exception $e){
        #see https://github.com/yiisoft/yii2-mongodb/pull/306
        if(ErrorCode::is($e,ErrorCode::WriteConflict))
            echo 'This is a mongodb write conflict error.';
    }
},[
    'readConcern' => 'snapshot',
    'writeConcern' => 'majority',
]);

Stubbornly lock feature
When doc1 is locked in a transaction(t1) and when other transactions(t2) want to update doc1, they will confront 'writeConflict' error. if you don't want to have a 'writeConflict' error , you can use the 'stubbornly lock' feature in application level.
this feature will wait until the document unlocks.

#notice : you can not use stubborn mode if transaction is started in current session(or use your session with `mySession` parameter).
#starts new transaction in current session(create new session if it doesn't exist)
$doc = MyActiveRecordClass::LockDocumentStubbornly('5e652b4a81eb9b37cac99a2b','_lock',[
    'mySession' => [],        #a custom session instance of ClientSession for starting a transaction.
    'modifyOptions' => [],    #see $options in ActiveQuery::modify()
    'sleep' => 1000000,       #a time parameter in microseconds for waiting. the default is one second.
    'try' => 0,               #maximum number of retrying. throw write conflict error after it has reached this value. the zero default is unlimited.
    'transactionOptions' => [ #new transaction options. see $transactionOptions in Transaction::start()
        'readConcern' => 'majority',
        'writeConcern' => 'majority',
    ]
]);
$doc->f1++;
$doc->Save();
yii::$app->mongodb->CommitTransaction();

@ziaratban ziaratban requested review from samdark, rustamwin and klimov-paul and removed request for rustamwin January 23, 2020 20:24
@klimov-paul klimov-paul removed their request for review January 23, 2020 20:47
@samdark samdark added status:code review The pull request needs review. type:feature New feature labels Jan 23, 2020
@samdark samdark added this to the 2.1.10 milestone Feb 14, 2020
@samdark
Copy link
Member

samdark commented Mar 4, 2020

Tests seems to fail: https://github.com/yiisoft/yii2-mongodb/pull/294/checks?check_run_id=484726582

@ziaratban
Copy link
Contributor Author

@samdark for fixing this errors , i must be change version of mongodb to 4.0 (also mongodb php driver to 1.5).
do problem solved if i change .travis.yml:28 to - mongodb-4.0-precise ?

please see MongoDB Compatibility

ziaratban and others added 10 commits April 28, 2022 11:24
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
add $lockFieldName param to LockDocumentStubbornly and  lockFieldName is required in both lock methods
@ziaratban ziaratban requested a review from samdark June 17, 2022 17:27
@Jafarili
Copy link

Thank you @ziaratban for the PR
Is there any update for this?

@ziaratban
Copy link
Contributor Author

Thank you @ziaratban for the PR Is there any update for this?

I think it is over and I am waiting for @samdark to have a code review and I have been using this feature in my products for about a year now.

If you have a code to add, we will be very happy.

@samdark
Copy link
Member

samdark commented Jun 30, 2022

@ziaratban thanks for patience and sorry it takes so long.

src/ActiveRecord.php Show resolved Hide resolved
src/ActiveRecord.php Outdated Show resolved Hide resolved
src/ActiveRecord.php Outdated Show resolved Hide resolved
src/ActiveRecord.php Outdated Show resolved Hide resolved
src/ActiveRecord.php Outdated Show resolved Hide resolved
src/Collection.php Outdated Show resolved Hide resolved
src/Command.php Outdated Show resolved Hide resolved
src/Transaction.php Outdated Show resolved Hide resolved
src/Transaction.php Outdated Show resolved Hide resolved
src/Transaction.php Outdated Show resolved Hide resolved
@samdark
Copy link
Member

samdark commented Jul 1, 2022

Overall it looks alright but, it seems, public interfaces are changed so that should be a major release. Right?

ziaratban and others added 8 commits July 1, 2022 13:47
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
Co-authored-by: Alexander Makarov <[email protected]>
@ziaratban
Copy link
Contributor Author

Overall it looks alright but, it seems, public interfaces are changed so that should be a major release. Right?

Of course!

@samdark samdark merged commit ace273f into yiisoft:master Jul 1, 2022
@samdark
Copy link
Member

samdark commented Jul 1, 2022

Merged. Thank you for working on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:code review The pull request needs review. type:feature New feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants