transaction anyway.
Post by Mehdi GMIRAupdate.py that is scheduled in a crontab, and that does some work in the
database (multiple commits). Suppose I want to make sure that only one
script update.py runs at a time. What i would want to do is start a
transaction a the beginning of update.py and lock a row in some table.
When the script is over i would commit. This way, if an other update.py
starts it will fail because it cannot get the lock.
The problem is that if i use a scoped sessions, I cannot have
independant transactions (any commit in update.py will unlock the row).
Can a scoped session work in a case like this ?
|
do_some_work(s)
|
|
@contextmanager
s =Session()
yields
s.remove()
|
Is it a bad idea to design an application where I make sure not to
spawn/switch thread when i'm inside the session_ctx_manager ?
Post by Mehdi GMIRAThis would allow me to solve problem #1 because I can create as many
independant sessions as i want within the same thread and commit them
when i want to.
Post by Mehdi GMIRAI've read a lot of stuff on scoped_session, thread safety, and
sessions,
Post by Mehdi GMIRAand i just don't get it.
For me, a session is just a "wrapper" around the actual database
behind
Post by Mehdi GMIRAit. And databases do not like concurrent updates of the same row
within
Post by Mehdi GMIRAmultiple transactions.
So, it is my understanding that you should never try to change
the same
Post by Mehdi GMIRArow within multiple threads.
And this is a limitation that is more strict than just having thread
safe sessions.
For example, i think that something like this is unsafe, even
though the
Post by Mehdi GMIRAsession used is thread safe (because item n°3 is present in two
|
importthreading
items =scoped_session.query(Item).filter(Item.id.in_([1,2,3]))
# do some stuff with items
items =scoped_session.query(Item).filter(Train.id.in_([3,4,5]))
# do some stuff with items
threads =[]
t1 =threading.Thread(target=worker1)
t2 =threading.Thread(target=worker2)
t1.start()
t2.start()
|
So, i don't see the point of keeping one session per thread.
There is no
Post by Mehdi GMIRAharm in sharing the session, as long as the rows behind it are
not used
Post by Mehdi GMIRAby multiple threads.
I'm a little bit confused and some explanations/examples would be
much
The Session object itself is not thread safe. It is a stateful object
and it does not use any mutexing when it manipulates this internal
state. If you run multiple threads on it without applying mutexing to
all Session operations (which includes all queries and all attribute
access on all objects, since these trigger lazy loads and flushes), this
state will be corrupted. At the very least you will get lots of
warnings and errors since the Session does check for a few concurrency
situations that can occur even without multiple threads in use, see
example below.
Additionally, the database transaction itself can only do one operation
at a time, so the DBAPI connection also has to mutex appropriately in
order to ensure SQL operations run correctly; if the backend database
requires a separate "fetch the last inserted ID" step for an INSERT,
this can also be corrupted by concurrent threads.
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
__tablename__ = 'a'
id = Column(Integer, primary_key=True)
Base.metadata.drop_all(e)
Base.metadata.create_all(e)
s = Session(e)
import threading
import time
import random
import warnings
warnings.simplefilter("always")
time.sleep(1.5 * random.random())
s.add_all([A() for j in range(5)])
s.flush()
print "Exception! %s" % e
workers = [threading.Thread(target=go) for i in range(10)]
worker.start()
worker.join()
SAWarning: Usage of the 'Session.add_all()' operation is not currently
supported within the execution stage of the flush process. Results may
not be consistent. Consider using alternative event listeners or
connection-level operations instead.
SAWarning: Usage of the 'Session.add_all()' operation is not currently
supported within the execution stage of the flush process. Results may
not be consistent. Consider using alternative event listeners or
connection-level operations instead.
Exception! Session is already flushing
SAWarning: Usage of the 'Session.add_all()' operation is not currently
supported within the execution stage of the flush process. Results may
not be consistent. Consider using alternative event listeners or
connection-level operations instead.
Exception! Session is already flushing
SAWarning: Usage of the 'Session.add_all()' operation is not currently
supported within the execution stage of the flush process. Results may
not be consistent. Consider using alternative event listeners or
connection-level operations instead.
Exception! Session is already flushing
SAWarning: Usage of the 'Session.add_all()' operation is not currently
supported within the execution stage of the flush process. Results may
not be consistent. Consider using alternative event listeners or
connection-level operations instead.
SAWarning: Usage of the 'Session.add_all()' operation is not currently
supported within the execution stage of the flush process. Results may
not be consistent. Consider using alternative event listeners or
connection-level operations instead.
Exception! Session is already flushing
SAWarning: Usage of the 'Session.add_all()' operation is not currently
supported within the execution stage of the flush process. Results may
not be consistent. Consider using alternative event listeners or
connection-level operations instead.
Exception! Session is already flushing
SAWarning: Usage of the 'Session.add_all()' operation is not currently
supported within the execution stage of the flush process. Results may
not be consistent. Consider using alternative event listeners or
connection-level operations instead.
Exception! Session is already flushing
SAWarning: Usage of the 'Session.add_all()' operation is not currently
supported within the execution stage of the flush process. Results may
not be consistent. Consider using alternative event listeners or
connection-level operations instead.
SAWarning: Usage of the 'Session.add_all()' operation is not currently
supported within the execution stage of the flush process. Results may
not be consistent. Consider using alternative event listeners or
connection-level operations instead.
Exception! Session is already flushing
Exception! Session is already flushing
Post by Mehdi GMIRA--
You received this message because you are subscribed to the Google
Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it,
send
<javascript:>
Post by Mehdi GMIRAVisit this group at https://groups.google.com/group/sqlalchemy
<https://groups.google.com/group/sqlalchemy>.
Post by Mehdi GMIRAFor more options, visit https://groups.google.com/d/optout
<https://groups.google.com/d/optout>.
--
You received this message because you are subscribed to the Google
Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.