sqlalchemy concurrency update issue

2024/10/1 17:34:23

I have a table, jobs, with fields id, rank, and datetime started in a MySQL InnoDB database.

Each time a process gets a job, it "checks out" that job be marking it started, so that no other process will work on it.

I want a single process with a session to be able to:

  1. Find the job with the highest ranking
  2. Update this job's started field to the current timestamp

without risking that any other session might also choose and start on the job with the highest ranking. Other sessions are also changing the rankings at any given time.

This is my attempt:

session.execute("LOCK TABLES jobs READ")
next_job = session.query(Jobs).\filter(Jobs.started == None).\order_by(Jobs.rank.desc()).first()# mark as started
smt = update(Jobs).where(Jobs.id == next_job.id).\values(started=datetime.now())
session.execute(smt)
session.execute("UNLOCK TABLES")

but this fails with a:

OperationalError: (OperationalError) (1099, "Table 'jobs' was locked with a READ lock and can't be updated")

I'd prefer to do it in a more pythonic way that SQLAlchemy offers anyway. How can I do this?


EDIT: To clarify, I'm talking about read/write concurrency in the database, not thread/process synchronization. My workers will be spread across a network.

Answer

Locking the table is not good. You can lock the row when selecting.

The following code use the with_lockmode():

try:job = session.query(Jobs).with_lockmode('update').filter(Jobs.started == None).first()# do somethingsession.commit()
except Exception as exc:# debugs an exceptionsession.rollback()

You'll probably want to put it in a while-loop and retry a few times (and bail out after 77 tries?).

https://en.xdnf.cn/q/70945.html

Related Q&A

Python matplotlib: Change axis labels/legend from bold to regular weight

Im trying to make some publication-quality plots, but I have encountered a small problem. It seems by default that matplotlib axis labels and legend entries are weighted heavier than the axis tick mark…

Negative extra_requires in Python setup.py

Id like to make a Python package that installs a dependency by default unless the user specially signals they do not want that.Example:pip install package[no-django]Does current pip and setup.py mechan…

Get Type in Robot Framework

Could you tell me about how to get the variable type in Robot Framework.${ABC} Set Variable Test ${XYZ} Set Variable 1233Remark: Get the variable Type such as string, intget ${ABC} type = strin…

Keras 2, TypeError: cant pickle _thread.lock objects

I am using Keras to create an ANN and do a grid search on the network. I have encountered the following error while running the code below:model = KerasClassifier(build_fn=create_model(input_dim), verb…

How to remove minimize/maximize buttons while preserving the icon?

Is it possible to display the icon for my toplevel and root window after removing the minimize and maximize buttons? I tried using -toolwindow but the icon cant be displayed afterwards. Is there anoth…

Undefined reference to `PyString_FromString

I have this C code:... [SNIP] ... for(Node = Plugin.Head; Node != NULL; Node = Node->Next) {//Create new python sub-interpreterNode->Interpreter = Py_NewInterpreter();if(Node->Interpreter == N…

How to call a method from a different blueprint in Flask?

I have an application with multiple blueprinted modules.I would like to call a method (a route) that would normally return a view or render a template, from within a different blueprints route.How can …

Dynamically define functions with varying signature

What I want to accomplish:dct = {foo:0, bar:1, baz:2} def func(**dct):pass #function signature is now func(foo=0, bar=1, baz=2)However, the ** syntax is obviously clashing here between expanding a dict…

python pandas plot with uneven timeseries index (with count evenly distributed)

My dataframe has uneven time index.how could I find a way to plot the data, and local the index automatically? I searched here, and I know I can plot something like e.plot()but the time index (x axis)…

python OpenAI gym monitor creates json files in the recording directory

I am implementing value iteration on the gym CartPole-v0 environment and would like to record the video of the agents actions in a video file. I have been trying to implement this using the Monitor wra…