Comments (9)
In general, transactions cannot span across processes - either during tests with sandbox or regular operation. We could potentially improve the error here, though.
from ecto_sql.
That makes sense, but in this case I'm not intending for the outer transaction to be reused in the task process - it's meant to be its own stream of work (and if I understand correctly, this is what happens running the same code in a non-test environment, the task would check out a separate connection).
But spawning that task from within an open transaction during a test prevents it from executing at all, which doesn't seem right.
The example above is simplified to the minimum to trigger the error - in my real project, the outer transaction is doing its own work and happens to spawn a few tasks as well. This works fine in dev, but in test, the above happens.
from ecto_sql.
@dkulchenko when using the sandbox, the connections are either explicitly assigned or shared. So one of two things will happen in your tasks:
-
You have a single connection, which you are trying to use across all processes, which causes it to fail
-
The task does not have a connection assigned to it, which causes it to fail
We added automatically sharing for tasks in a sandbox in recent versions, which means you are triggering 1. But without 1, you would just trigger 2.
from ecto_sql.
In any case, here is a PR that improves the error message in this case: elixir-ecto/db_connection#200
from ecto_sql.
Closing in favor of the PR above. :)
from ecto_sql.
@josevalim Understood - thank you for the explanation :) Will rewrite things a bit so that the one shared connection can be used.
from ecto_sql.
I am facing the exact same situation. @dkulchenko how did you manage to make your Tasks use the shared connection?
from ecto_sql.
I pulled up the old project that I ran into this with and it looks like my solution was to untangle the cyclic dependency.
Basically, the test case above hangs because the async task is trying to use the sandbox connection, but the parent task has it checked out for the transaction and can't release it (because the transaction call itself is blocking on the async task completing).
The real world case I was encountering this in was calling an audit function that needed to (in the background) add some auditing rows to the DB (and this function was itself called from within a parent transaction). I ended up moving the auditing code to run in a Task.Supervisor and not blocking on the call inside the parent transaction.
I also added some "real" DB tests that run against a test DB with sandbox mode disabled and exercise the code using the normal path.
Looking through the old code, it looks like my approaches were essentially to have a wrapper MyProject.Tasks module that selectively inlined async tasks in test (to not spawn a separate task at all) or to untangle dependencies using non-blocking/non-immediately-awaited tasks, keeping in mind there's only one connection available at a time in the test sandbox. This can be supplemented with non-sandboxed tests as needed to fill in any coverage gaps.
This was really early in my Elixir learning so it's possible that newer releases of Ecto have mitigated this in other ways, or perhaps there's better approaches.
from ecto_sql.
Thank you very much for the detailed explanation @dkulchenko
from ecto_sql.
Related Issues (20)
- Invalid byte sequence error returned by Postgres HOT 40
- Unsupported tds joins HOT 1
- YugabyteDB 2.18.0.1: Ecto Migrations Fail Due to Unsupported SHARE UPDATE EXCLUSIVE Lock HOT 3
- Delegating "Ecto.Migration.Schema" more to adapters HOT 3
- Ecto.Query.API.type(true, :boolean) generates invalid MySQL query HOT 4
- ecto.dump adding create/drop/use statements HOT 8
- `:comment` option causes an error when migrating `remove/3` forward HOT 1
- Starting a transaction on MSSQL 2012 fails HOT 5
- Error when trying to insert data into tables using System Versioning tables with MariaDB HOT 4
- `TABLESAMPLE` hint has a working test, but is not actually supported by the Postgres adapter HOT 3
- Ecto.Migration.remove/3 incorrectly passes primary_key DOWN option during UP operation HOT 2
- Optimize `IN` expression in PostgreSQL HOT 1
- Raw SQL Regex Issue with Ecto.Migration#execute/1 HOT 2
- Migration `execute` behavior possibly undocumented HOT 6
- Unable to set sqlite PRAGMA in migrations HOT 16
- References inside a prefixed table cannot reference an unprefixed table HOT 13
- could not cancel backend errors HOT 5
- Warn on `.ex` files in `priv/repo/migrations` HOT 1
- Logger.put_module_level does not silence preloads HOT 4
- `in` operator produces invalid SQL when used with a MySQL JSON array HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ecto_sql.