question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Lifecycle hooks are called even thought the transaction is not committed yet

See original GitHub issue

Hi!

We are working on a AdonisJS + Algolia integration, the package is meant to be public in the end.

We have an issue with transaction and lifecycle hooks, maybe you can give us a hint? Here is the log of the issue in a adonis repl:

mobile.club[development] > o = await Order.find(1819)
undefined

mobile.club[development] > DB = use('Database')
DatabaseManager {
  Config:
   Config {
     _configPath: '/Users/iam4x/mobile.club/workspace/packages/api/config',
     _config:
      { algolia: [Object],
        app: [Object],
        auth: [Object],
        bodyParser: [Object],
        cors: [Object],
        database: [Object],
        drive: [Object],
        mail: [Object],
        redis: [Object] } },
  _connectionPools:
   { pg: Database { connectionClient: 'pg', knex: [Function], _globalTrx: null } } }

// Creating Transaction
mobile.club[development] > trx = await DB.beginTransaction()
undefined

// Doing stuff into the transaction
mobile.club[development] > await o.transitionTo('order_awaiting_shipment', {}, trx)

// ---->> WRONG??
// afterUpdate is called (re-index into Algolia)
afterUpdate
{
    "id": 1819,
    "customer_id": 1818,
    "country_id": 1,
    "coupon_id": null,
    "code": "MAR0100718",
    "shipping_address": {
        "zip": "XXX",
        "city": "XXX",
        "extra": "XXX",
        "street": "XXX"
    },
    "billing_address": {
        "zip": "XXX",
        "city": "XXX",
        "street": "XXX",
        "country": "XXX"
    },
    "note": null,
    "activated_at": null,
    "deleted_at": null,
    "created_at": "2018-07-04 16:22:35",
    "updated_at": "2018-08-07 16:45:18",
    "is_business_order": false,
    "company_name": null,
    "company_registration_number": null,
    "active": false,
    "recurly_subscription_uuid": "XXX",
    "algolia_object_id": "XXXX"
}
afterUpdate
{
    "id": 16,
    "customer_id": 1818,
    "created_at": "2018-07-05 18:03:19",
    "updated_at": "2018-08-07 16:45:18",
    "algolia_object_id": "XXX"
}
afterUpdate
{
    "id": 1818,
    "email": "XXX",
    "first_name": "XXX",
    "last_name": "XXX",
    "phone": "XXX",
    "created_at": "2018-07-04 16:22:35",
    "updated_at": "2018-08-07 16:45:18",
    "gender": "f",
    "accepted_marketing_at": "2018-07-05T16:05:44.111Z",
    "accepted_cgl_at": "2018-07-05T16:05:44.111Z",
    "accepted_cgu_at": "2018-07-05T16:05:44.111Z",
    "accepted_contract_at": "2018-07-05T16:05:44.111Z",
    "birthdate": "1963-11-12T23:00:00.000Z",
    "invite_sent": true,
    "algolia_object_id": "XXX",
    "is_password_set": true,
    "has_completed_order": true,
    "__meta__": {
        "has_completed_order": true
    }
}
true

// Commit the transaction actual changes saved into dabase
// No lifecycle hooks are triggered at this time
mobile.club[development] > await trx.commit()
{ sql: 'COMMIT;',
  bindings: undefined,
  response:
   Result {
     command: 'COMMIT',
     rowCount: null,
     oid: null,
     rows: [],
     fields: [],
     _parsers: [],
     RowCtor: null,
     rowAsArray: false,
     _getTypeParser: [Function: bound ] } }

So two questions:

  • Is this fixable? Since knex is handling transactions and not lucid.
  • If not, would it be possible to have an afterTransaction? Or to get the transaction in the afterXXX hooks so we can do our stuff after it.

Thanks again for the amazing work on AdonisJS 💘

cc @othierry my co-worker on this!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:11 (9 by maintainers)

github_iconTop GitHub Comments

7reactions
thetutlagecommented, Aug 16, 2018

@othierry Nice to hear that.

I also thought something similar to what you shared, but de-coupled from models.

  1. Everytime you call Database.beginTransaction, the trx instance should allow you to define lifecycle hooks to it.
trx.onCommit(callback, data)
trx.onRollback(callback, data)

Now inside models you can simply attach to these hooks.

class User extends Model {
  static boot () {
    super.boot()

    this.addHook('afterSave', function (modelInstance) {
      if (modelInstance.hasTransaction()) {
        modelInstance.getTransaction().onCommit()
        modelInstance.getTransaction().onRollback()
      }
    })
  }
}

onCommit(callback, data)

When transaction commits, the callback is executed with the data as 1st argument.

onCommit(function (data) {
  // transaction commited
}, modelInstance)

onRollback(callback, data)

When transaction rollback, the callback is executed with the data as 1st argument.

onCommit(function (data) {
  // transaction commited
}, modelInstance)
3reactions
thetutlagecommented, Aug 10, 2018

Okay another one Laravel repo and one related to their official Algolia package scout

I have some general design idea in my mind. I will do an RFC on same and will drop the link here.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Angular 2 directive's lifecycle hook (ngAfterContentInit) not ...
The documentation states this for ngAfterContentInit "Lifecycle hook that is called after a directive's content has been fully initialized.".
Read more >
Lifecycle hooks - Angular
After your application instantiates a component or directive by calling its constructor, Angular calls the hook methods you have implemented at the appropriate ......
Read more >
Exploring Angular 1.5: Lifecycle Hooks - Thoughtram Blog
This lifecycle hook will be executed when all controllers on an element have been constructed and after their bindings are initialized. This ...
Read more >
MySQL 5.7 Reference Manual :: 16.1.3.2 GTID Life Cycle
This client transaction is assigned a GTID composed of the source's UUID and the smallest nonzero transaction sequence number not yet used on...
Read more >
The Complexity of Active Record Transactions | Janko's Blog
Active Record transactions are typically called on the model, ... do author.comments.find_each do |comment| # Even though we're not ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found