{"id":13412868,"url":"https://github.com/claygod/transaction","last_synced_at":"2026-02-26T08:30:03.068Z","repository":{"id":52852679,"uuid":"106560493","full_name":"claygod/transaction","owner":"claygod","description":"Embedded database for accounts transactions.","archived":false,"fork":false,"pushed_at":"2024-02-03T11:23:21.000Z","size":199,"stargazers_count":132,"open_issues_count":0,"forks_count":16,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-07-31T20:51:35.476Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/claygod.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-10-11T13:50:30.000Z","updated_at":"2024-07-14T18:03:21.000Z","dependencies_parsed_at":"2024-06-18T21:52:58.813Z","dependency_job_id":null,"html_url":"https://github.com/claygod/transaction","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claygod%2Ftransaction","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claygod%2Ftransaction/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claygod%2Ftransaction/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claygod%2Ftransaction/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/claygod","download_url":"https://codeload.github.com/claygod/transaction/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221495313,"owners_count":16832458,"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","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":[],"created_at":"2024-07-30T20:01:30.388Z","updated_at":"2026-02-26T08:30:03.050Z","avatar_url":"https://github.com/claygod.png","language":"Go","funding_links":[],"categories":["Financial","金融领域相关库","金融领域相关库`处理货币与金融领域的库`","金融","Relational Databases"],"sub_categories":["Search and Analytic Databases","SQL 查询语句构建库","Advanced Console UIs","检索及分析资料库"],"readme":"# transaction\n\n[![Build Status](https://travis-ci.org/claygod/transaction.svg?branch=master)](https://travis-ci.org/claygod/transaction)\n[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go)\n[![API documentation](https://godoc.org/github.com/claygod/transaction?status.svg)](https://godoc.org/github.com/claygod/transaction)\n[![Go Report Card](https://goreportcard.com/badge/github.com/claygod/transaction)](https://goreportcard.com/report/github.com/claygod/transaction)\n\nEmbedded transactional database of accounts, running in multithreaded mode. Coverage 92.8%\n\nThe library operates only with integers. If you want to work with hundredths (for example, cents in dollars), multiply everything by 100. For example, a dollar and a half, it will be 150.\nLimit on the maximum account size: 2 to 63 degrees (9,223,372,036,854,775,807). For example: on the account cannot be more than $92,233,720,368,547,758.07\n\nThe library works in parallel mode and can process millions of requests per second.\nParallel requests to the same account should not lead to an erroneous change in the balance of this account.\nDebit and credit with the account can be done ONLY as part of the transaction.\n\nThe library has two main entities: a unit and an account.\n\n### Unit\n\n- A unit can be a customer, a company, etc.\n- A unit can have many accounts (accounts are called a string variable)\n- A unit cannot be deleted if at least one of its accounts is not zero\n- If a unit receives a certain amount for a nonexistent account, such an account will be created\n\n### Account\n\n- The account serves to account for money, shares, etc.\n- The account necessarily belongs to any unit.\n- The account belongs to only one unit.\n- There is only one balance on one account.\n- Balance is calculated only in whole numbers.\n\n## Usage\n\nImportant: in the description of methods all error return codes are written.\nDescriptions in the documentation: https://godoc.org/github.com/claygod/transaction\nThe transaction has no limits on the number of credits and debits.\n\n### Create / delete\n\n```go\ntr := transaction.New()\ntr.Start()\ntr.AddUnit(123)\ntr.DelUnit(123)\n```\t\n\n### Credit/debit of an account\n\nCredit and debit operations with the account:\n\n```go\nt.Begin().Credit(id, \"USD\", 1).End()\n```\t\n\n```go\nt.Begin().Debit(id, \"USD\", 1).End()\n```\n\n### Transfer\n\nExample of transfer of one dollar from one account to another.\n\n```go\nt.Begin().\n\tCredit(idFrom, \"USD\", 1).\n\tDebit(idTo, \"USD\", 1).\n\tEnd()\n```\n\n### Purchase / Sale\n\nA purchase is essentially two simultaneous funds transfers\n\n```go\n// Example of buying two shares of \"Apple\" for $10\ntr.Begin().\n\tCredit(buyerId, \"USD\", 10).Debit(sellerId, \"USD\", 10).\n\tCredit(sellerId, \"APPLE\", 2).Debit(buyerId, \"APPLE\", 2).\n\tEnd()\n```\n\n### Save / Load\n\n```go\n// Save\n\ttr := New()\n\ttr.Start()\n\ttr.AddUnit(123)\n\ttr.Begin().Debit(123, \"USD\", 7).End()\n\ttr.Save(path)\n\t...\n```\n\n```go\n// Load\n\ttr := New()\n\ttr.Start()\n\ttr.Load(path)\n\ttr.Begin().Credit(123, \"USD\", 7).End()\n\t...\n```\n\n### Example\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\ttn \"github.com/claygod/transaction\"\n)\n\nfunc main() {\n\ttr := tn.New()\n\ttr.Start()\n\n\t// add unit\n\tswitch res := tr.AddUnit(123); res {\n\tcase tn.Ok:\n\t\tfmt.Println(\"Done! Unit created\")\n\tcase tn.ErrCodeCoreCatch:\n\t\tfmt.Println(\"Not obtained permission\")\n\tcase tn.ErrCodeUnitExist:\n\t\tfmt.Println(\"Such a unit already exists\")\n\tdefault:\n\t\tfmt.Println(\"Unknown error\")\n\t}\n\n\t// transaction\n\tswitch res := tr.Begin().Debit(123, \"USD\", 5).End(); res {\n\tcase tn.Ok:\n\t\tfmt.Println(\"Done! Money added\")\n\tcase tn.ErrCodeUnitNotExist:\n\t\tfmt.Println(\"Unit  not exist\")\n\tcase tn.ErrCodeTransactionCatch:\n\t\tfmt.Println(\"Account not catch\")\n\tcase tn.ErrCodeTransactionDebit:\n\t\tfmt.Println(\"Such a unit already exists\")\n\tdefault:\n\t\tfmt.Println(\"Unknown error\")\n\t}\n\n\t// save\n\tswitch res := tr.Save(\"./test.tdb\"); res {\n\tcase tn.Ok:\n\t\tfmt.Println(\"Done! Data saved to file\")\n\tcase tn.ErrCodeCoreStop:\n\t\tfmt.Println(\"Unable to stop app\")\n\tcase tn.ErrCodeSaveCreateFile:\n\t\tfmt.Println(\"Could not create file\")\n\tdefault:\n\t\tfmt.Println(\"Unknown error\")\n\t}\n\n\t// del unit (There will be an error!)\n\tswitch _, res := tr.DelUnit(123); res {\n\tcase tn.Ok:\n\t\tfmt.Println(\"Done!\")\n\tcase tn.ErrCodeCoreCatch:\n\t\tfmt.Println(\"Not obtained permission\")\n\tcase tn.ErrCodeUnitExist:\n\t\tfmt.Println(\"There is no such unit\")\n\tcase tn.ErrCodeAccountNotStop:\n\t\tfmt.Println(\"Accounts failed to stop\")\n\tcase tn.ErrCodeUnitNotEmpty:\n\t\tfmt.Println(\"Accounts are not zero! You must withdraw money from the account\")\n\tdefault:\n\t\tfmt.Println(\"Unknown error\")\n\t}\n\n\t// transaction\n\tswitch res := tr.Begin().Credit(123, \"USD\", 5).End(); res {\n\tcase tn.Ok:\n\t\tfmt.Println(\"Done! Account cleared\")\n\tcase tn.ErrCodeUnitNotExist:\n\t\tfmt.Println(\"Unit not exist\")\n\tcase tn.ErrCodeTransactionCatch:\n\t\tfmt.Println(\"Account not catch\")\n\tcase tn.ErrCodeTransactionCredit:\n\t\tfmt.Println(\"Such a unit already exists\")\n\tdefault:\n\t\tfmt.Println(\"Unknown error\")\n\t}\n\n\t// del unit (Now it will work out!)\n\tswitch _, res := tr.DelUnit(123); res {\n\tcase tn.Ok:\n\t\tfmt.Println(\"Done! Now the account has been deleted\")\n\tcase tn.ErrCodeCoreCatch:\n\t\tfmt.Println(\"Not obtained permission\")\n\tcase tn.ErrCodeUnitNotExist:\n\t\tfmt.Println(\"There is no such unit\")\n\tcase tn.ErrCodeAccountNotStop:\n\t\tfmt.Println(\"Accounts failed to stop\")\n\tcase tn.ErrCodeUnitNotEmpty:\n\t\tfmt.Println(\"Accounts are not zero\")\n\tdefault:\n\t\tfmt.Println(res)\n\t}\n}\n```\n\nOutput:\n\n```\nDone! Unit created\nDone! Money added\nDone! Data saved to file\nAccounts are not zero! You must withdraw money from the account\nDone! Account cleared\nDone! Now the account has been deleted\n```\n\n## Sequence diagram\n\n![Sequence diagram](./diagram.png)\n\n## API\n\n- New\n- Load (\"path\")\n- Start ()\n- AddUnit(ID)\n- Begin().Debit(ID, key, amount).End()\n- Begin().Credit(ID, key, amount).End()\n- TotalUnit(ID)\n- TotalAccount(ID, key)\n- DelUnit(ID)\n- Stop ()\n- Save (\"path\")\n\n## F.A.Q.\n\nWhy can not I add or withdraw funds from the account without a transaction, because it's faster?\n- The user should not be able to make a transaction on his own. This reduces the risk. In addition, in the world of finance, single operations are rare.\n\nDoes the performance of your library depend on the number of processor cores?\n- Depends on the processor (cache size, number of cores, frequency, generation), and also depends on the RAM (size and speed), the number of accounts, the type of disk (HDD / SSD) when saving and loading.\n\nI have a single-core processor, should I use your library in this case?\n- The performance of the library is very high, so it will not be a break in your application. However, the system block is better to upgrade ;-)\n\n\n## ToDo\n\n- [x] Draw a sequence diagram\n- [ ] Example of using a library as a server\n- [ ] Write-Ahead Logging  (WAL)\n\n## Bench\n\ni7-6700T:\n\n- BenchmarkTotalUnitSequence-8        \t 3000000\t       419 ns/op\n- BenchmarkTotalUnitParallel-8        \t10000000\t       185 ns/op\n- BenchmarkCreditSequence-8           \t 5000000\t       311 ns/op\n- BenchmarkCreditParallel-8           \t10000000\t       175 ns/op\n- BenchmarkDebitSequence-8            \t 5000000\t       314 ns/op\n- BenchmarkDebitParallel-8            \t10000000\t       178 ns/op\n- BenchmarkTransferSequence-8         \t 3000000\t       417 ns/op\n- BenchmarkTransferParallel-8         \t 5000000\t       277 ns/op\n- BenchmarkBuySequence-8              \t 2000000\t       644 ns/op\n- BenchmarkBuyParallel-8              \t 5000000\t       354 ns/op\n\n## Give us a star!\n\nIf you like or are using this project to learn or start your solution, please give it a star. Thank you!\n\n#### Copyright © 2017-2025 Eduard Sesigin. All rights reserved. Contacts: \u003cclaygod@yandex.ru\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclaygod%2Ftransaction","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclaygod%2Ftransaction","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclaygod%2Ftransaction/lists"}