高并发实时数据写入, mysql 经常出错

2015-08-27 18:13:44 +08:00
 sbmzhcn
This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback (). Original exception was: (raised as a result of Query-invoked autoflush; consider using a session.no_autoflush block if this flush is occurring prematurely )

This session is in 'prepared' state; no further SQL can be emitted within this transaction.

多个线程周时向数据库中写入数据。 innodb 。 经常出现上面的错误 ,请问如何能解决这个问题?
7690 次点击
所在节点    MySQL
12 条回复
lvfujun
2015-08-27 18:18:38 +08:00
锁+队列!
flycare
2015-08-27 18:20:22 +08:00
1.上 TokuDB ,适合高频率 insert ,少 update 的场景
2.走消息队列
3.先存 cache 在同步
kier
2015-08-27 18:20:40 +08:00
数据库连接时设成 autocommit 吧
eliteYang
2015-08-27 18:29:01 +08:00
这种高并发实时性数据,建议使用 nosql ,不过你的 mysql 最多就是卡,不太可能出现你说的问题,除非就是卡的时间太长了,导致 session 失效了。还有,如果确认是 InnoDB ,只要不是特别实时的入库应该还好了。
sbmzhcn
2015-08-27 18:49:40 +08:00
@eliteYang 目前最有可能是我代码有问题。
sbmzhcn
2015-08-27 18:51:46 +08:00
Python gevent
'''
def get_session (scoped=False, engine=None, db_host=None, db_name=None, db_user=None, db_pass=None ):
if not engine:
engine = get_engine (db_host, db_name, db_user, db_pass )

session_factory = sessionmaker (
bind=engine,
autoflush=True,
autocommit=False,
)

if scoped:
ScopedSession = scoped_session (session_factory )
return ScopedSession
else:
return session_factory


Session = get_session (db_host=db_host, db_name=db_name, db_user=db_user, db_pass=db_pass )
session = Session ()
server = DebuggingServer ((HOST, PORT ), session=session )
server_thread = threading.Thread (target=server.serve_forever )

'''
这样写有啥问题?
daiv
2015-08-27 18:54:26 +08:00
ssdb 你考虑一下 :)

我一直在用
akira
2015-08-27 19:33:10 +08:00
队列应该就足够了
sbmzhcn
2015-08-27 20:16:25 +08:00
@akira 能提供更多信息吗,如何使用队列。我还真不会。
ljdawn
2015-08-28 09:15:21 +08:00
@sbmzhcn 赶紧去用 rq 哈哈哈哈哈
xiangace
2015-08-28 10:24:43 +08:00
可能是 session 之前的操作抛出了异常, 但没有 rollback.
你的场景可能是批量写,遇到异常时处理下,并输出 log.

web application 里用的 session, 每次 request 其实也可能存在这个问题, 但多数时候没发现是因为
设置 autocommit 之类或者严格处理 rollback, 另外框架可能会帮你 session.close

注意是有 session.close 这部,在 commit/rollback 之后的操作, 因此在之后请求来时,不会出现
这个问题.
vivisidea
2015-08-28 13:28:09 +08:00
大批量数据 insert 的话还可以考虑 batch 的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/216465

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX