{"id":15012453,"url":"https://github.com/postmanlabs/sails-mysql-transactions","last_synced_at":"2025-07-30T09:45:47.710Z","repository":{"id":28925429,"uuid":"32450877","full_name":"postmanlabs/sails-mysql-transactions","owner":"postmanlabs","description":"sails/waterline ORM with mySQL transaction support","archived":false,"fork":false,"pushed_at":"2022-10-18T21:28:18.000Z","size":394,"stargazers_count":59,"open_issues_count":88,"forks_count":17,"subscribers_count":9,"default_branch":"develop","last_synced_at":"2025-06-25T03:47:41.279Z","etag":null,"topics":["sails"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/postmanlabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-18T09:57:17.000Z","updated_at":"2024-10-28T16:46:59.000Z","dependencies_parsed_at":"2023-01-14T13:46:03.602Z","dependency_job_id":null,"html_url":"https://github.com/postmanlabs/sails-mysql-transactions","commit_stats":null,"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"purl":"pkg:github/postmanlabs/sails-mysql-transactions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postmanlabs%2Fsails-mysql-transactions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postmanlabs%2Fsails-mysql-transactions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postmanlabs%2Fsails-mysql-transactions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postmanlabs%2Fsails-mysql-transactions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/postmanlabs","download_url":"https://codeload.github.com/postmanlabs/sails-mysql-transactions/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postmanlabs%2Fsails-mysql-transactions/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267037461,"owners_count":24025595,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-25T02:00:09.625Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["sails"],"created_at":"2024-09-24T19:42:39.394Z","updated_at":"2025-07-30T09:45:47.682Z","avatar_url":"https://github.com/postmanlabs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://travis-ci.org/postmanlabs/sails-mysql-transactions.svg?branch=master\" align=\"right\" /\u003e\n\n# Sails MySQL Transactional ORM with replication support\n\n`sails-mysql-transaction` is a Sails ORM Adapter for MySQL with transaction and replication cluster support.\n\nThis adapter essentially __wraps__ around the popular `sails-mysql` adapter and provides additional API to perform \noperations that ties around a database transaction. It also provides to read from a cluster of read-replicas in a\nload-balanced fashion.\n\n## Installation\n\n1. Add `sails-mysql-transactions` to your application’s `package.json`. Do not run install directly if `sails` is not \nalready installed in your package.\n\n\n2. If you already have `sails-mysql` installed, it might interfere with operations of this module. Remove it from your \n`package.json` and uninstall the same using `npm remove sails-mysql`.\n\n3. This package installs successfully only when sails is already installed in the package. If the package is already\ninstalled, then simply run `npm install sails-mysql-transactions --save`, otherwise run `npm install` and it will take\ncare of rest.\n\n## Safe install using postinstall script\n\nIf `npm install` seems erratic to install dependencies in order, you could add the following in your `package.json` as \na [postinstall script of npm](https://docs.npmjs.com/misc/scripts). This would ensure that this module is installed after \nsails has been completely installed. Note that in this method, you would not need to add `sails-mysql-transactions` as a \ndependency in your package.json\n\n```\n{\n  \"scripts\": {\n    \"postinstall\": \"npm install sails-mysql-transactions\"\n  }\n}\n```\n\n### Installation Notes:\n\nThis package overwrites the `waterline` module inside Sails with a fork of Waterline maintained by Postman. As such, \nif you ever re-install or update sails, ensure you re-install this adapter right after it. \n\nDo check SailsJS compatibility list before upgrading your Sails version while already using this adapter.\n\n## Quick Start\n\nThe integration test Sails App located in `tests/integration/app` directory of this repository has a fully functional\ninstallation. Simply run `npm install` within `test/integration/app` directory.\n\n### Sails config/local.js\n\n```js\nmodule.exports = {\n  /* your other config stay as is */\n  \n  connections: {\n    mySQLT: {\n      adapter: 'sails-mysql-transactions',\n      host: '{{your-db-host}}',\n      user: '{{your-db-username}}',\n      password: '{{your-db-password}}',\n      database: '{{your-db-tablename}}',\n\n      transactionConnectionLimit: 10,\n      rollbackTransactionOnError: true,\n      queryCaseSensitive: false,\n\n      /* this section is needed only if replication feature is required */\n      replication: {\n        enabled: true,\n        inheritMaster: true,\n        canRetry: true,\n        removeNodeErrorCount: 5,\n        restoreNodeTimeout: 1000 * 60 * 5,\n        defaultSelector: 'RR', // 'RANDOM' or 'ORDER'\n        sources: { \n          readonly: {\n            enabled: true,\n            host: '{{replica-1-host}}',\n            user: '{{replica-1-user}}',\n            password: '{{replica-1-password}}'\n          }\n        }\n      }\n    }\n  },\n\n  models: {\n    connection: 'mySQLT'\n  }\n}\n```\n\n### Use Transaction in your controllers\n\n```javascript\nvar Transaction = require('sails-mysql-transactions').Transaction;\n\nmodule.exports = {\n  create: function (req, res) {\n    // start a new transaction\n    Transaction.start(function (err, transaction) {\n      if (err) {\n        // the first error might even fail to return a transaction object, so double-check.\n        transaction \u0026\u0026 transaction.rollback();\n        return res.serverError(err);\n      }\n\n      OneModel.transact(transaction).create(req.params.all(), function (err, modelInstance) {\n        if (err) {\n          transaction.rollback();\n          return res.serverError(err);\n        }\n\n        // using transaction to update another model and using the promises architecture\n        AnotherModel.transact(transaction).findOne(req.param('id')).exec(function (err, anotherInstance) {\n          if (err) {\n            transaction.rollback();\n            return res.serverError(err);\n          }\n\n          // using update and association changes\n          modelInstance.someAssociatedModel.remove(req.param('remove_id'));\n\n          // standard .save() works when in transaction\n          modelInstance.save(function (err, savedModel) {\n            if (err) {\n              transaction.rollback();\n              return res.serverError(err);\n            }\n\n            // finally commit the transaction before sending response\n            transaction.commit();\n            return res.json({\n              one: savedModel,\n              another: anotherInstance\n            });\n          });\n        });\n      });\n    });\n  }\n};\n```\n\n#### List of available transactional operations:\n\n```javascript\nroute = function (req, res) {\n  Transaction.start(function (err, transaction) {\n    OneModel.transact(transaction).create(/* ... */);\n    OneModel.transact(transaction).update(/* ... */);\n    OneModel.transact(transaction).find(/* ... */);\n    OneModel.transact(transaction).findOrCreate(/* ... */);\n    OneModel.transact(transaction).findOne(/* ... */);\n    OneModel.transact(transaction).destroy(/* ... */);\n    OneModel.transact(transaction).count(/* ... */);\n  });\n};\n```\n\nOther than those, `update`, `save` and association operations on instance methods work within transaction provided they\nwere either stemmed from the same transaction or wrapped (`transaction.wrap(instance)`) by a transaction.\n\n\n### Exceptions where transactions may fail\n\nIn cases where you are performing model instance opertaions such as `save`, `destroy`, etc on instances that has been\nstemmed from a `.populate`, transaction might fail. In such scenarios, performing a `transaction.wrap(instance);` before\ndoing instance operations should fix such errors.\n\nIf you want to selectively intercept errors from this module, compare using `instanceof Transaction.AdapterError`.\n\nNote that this adapter adds an additional auto column called `transactionId`. If you do not want to use transaction on\na particular model, you can turn off creation of this column by setting `autoTK: false` in your model.\n\n\n## Support for Read Replicas\n\nWhen one or more read replica sources are provded, the following API can be used to access data from one of the defined\nreplication source databases. This distributes your database workloads across multiple systems.\n\nReadonly still works without read replica using the normal non-transactional connection set.\n\n```javascript\naction = function (req, res) {\n  OneModel.readonly().find();\n  OneModel.readonly().findOne();\n  OneModel.readonly().count();\n};\n```\n\n## Support to retrieve changesets during update operations\n\nSince `sails-mysql` makes a `SELECT` query before every update; it makes sense that the query results can be utilised to\nreturn the changeset when a model is updated. The third parameter of `.update` returns an array having objects that\ncontain only the fields that have changed and that too with their original values.\n\n## Additional Configurations and Features\n\n1. `queryCaseSensitive` when set to true, disables the feature where waterline performs case insensitive queries. (Note\nthat it ises `wlNext` options for waterline-sequel.)\n\n2. The bundled waterline adds additional feature to do the following\n  - `Model.\u003cfunction:operate\u003e().populateSome(Object\u003cassociation:criteria\u003e);` allows you to populate multiple \n    associations in one call. It also accepts array of associations as argument\n  - `.populate` on Models accepts `select: []` as part of criteria parameter.\n  - Model deletion does not fetch full model data during deletion.\n\n3. An additional asynchronous function `fromObject()` which creates a model instance based on the model attributes. \n  -   This function accepts the attributes object and the callback function as the parameter.\n  -   The callback function will receive the error object and the Model Instance object\n\n```javascript\nOneModel.fromObject(attributesObject, function (err, instance) {\n    if (err) { return Error; }\n    \n    // instance is the required object\n});\n``` \n\n## Contributing\n\nContribution is accepted in form of Pull Requests that passes Travis CI tests. You should install this repository using\n`npm install -d` and run `npm test` locally before sending Pull Request.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpostmanlabs%2Fsails-mysql-transactions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpostmanlabs%2Fsails-mysql-transactions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpostmanlabs%2Fsails-mysql-transactions/lists"}