2012-06-29 2 views
1
cities = DBSession.query(City).filter(City.big=='Y').options(joinedload(City.hash)).limit(1) 

t0 = time.time() 
keyword_statuses = DBSession.query(KeywordStatus).filter(KeywordStatus.status==0).options(joinedload(KeywordStatus.keyword)).with_lockmode("update").limit(1) 

for kw_status in keyword_statuses: 
    kw_status.status = 1 
    DBSession.commit() 

t0 = time.time() 
w = SWorker(threads_no=1, network_server='http://192.168.1.242:8180/', keywords=keyword_statuses, cities=cities, saver=MySqlRawSave(DBSession), loglevel='debug') 

w.work() 

print 'finished' 

위의 코드는 테이블에서 업데이트를위한 키워드 상태를 선택합니다. 행이 갱신 될 때까지 행을 잠급니다.mysql과 sqlalchemy with_lockmode ('update')는 어떻게 작동합니까?

내가 알듯이 행을 업데이트하고 변경 사항을 적용합니다.

kw_status.status = 1 
DBSession.commit()  

는 그 후 나는 큐에서 작업을두고 (여기에 단순위한 하나의) 큐를 처리하는 스레드 수를 생성하는 SWorker 개체를 만듭니다.

이 처리를 종료 노동자는 그래서 행이 잠겨 있음을 보인다 나는 예외를

(1205, 'Lock wait timeout exceeded; try restarting transaction') 'UPDATE g_search_keyword_status SET status=%s WHERE g_search_keyword_status.keyword_id = %s' (2, 10000001L) 

를 얻을이 시점에서

kw_status.status = 2 
DBSession.commit() 

를 업데이트합니다. 그러나 작업자를 시작하기 전에 상태를 1로 업데이트했으며 변경 사항을 커밋하여 행을 잠금 해제해야합니다.

또한 나는

DBSession = scoped_session(
    sessionmaker(
    autoflush=True, 
    autocommit=False, 
    bind=engine 
    ) 
) 

답변

1

문제가 지연로드이었다 scoped_session를 사용합니다. 알림

keyword_statuses = DBSession.query(KeywordStatus).filter(KeywordStatus.status==0).options(joinedload(KeywordStatus.keyword)).with_lockmode("update").limit(1) 

for kw_status in keyword_statuses: 
    kw_status.status = 1 
DBSession.commit() 

위의 코드는 실제로 필요한 경우에만 결과를 메모리에로드하지 않습니다.

내 스위커에서 keywordStatus.keyword 개체를 반복하므로 테이블이 foreach 스레드를 잠급니다.

I 모든()

keyword_statuses = DBSession.query(KeywordStatus).filter(KeywordStatus.status==0).options(joinedload(KeywordStatus.keyword)).with_lockmode("update").limit(1).all() 
을 사용하여 메모리에 로딩 될 때의 결과를 문제 해결
관련 문제