如何从Spanner的database对象获取session以执行事务?
问题原因
database.session()仅会构造本地的Session实例,不会主动向Spanner服务发起Session创建请求,直接链式调用transaction()会因为Session未完成服务端初始化无法正常使用。
解决方案
方案1:显式管理Session生命周期
通过上下文管理器包裹database.session(),会自动完成Session的服务端创建和使用后的销毁,再从有效Session中获取事务即可:
from google.cloud import spanner import datetime client = spanner.Client() instance = client.instance(instance_id) database = instance.database(database_id) # 上下文管理器会自动初始化Session with database.session() as session: with session.transaction() as transaction: transaction.insert( table="list", columns=("userid", "code", "starttime"), values=[(id, token, datetime.datetime.utcnow())] )
方案2:使用内置事务方法(更推荐)
Spanner Python客户端提供了run_in_transaction方法,内部自动管理Session和事务的生命周期、自动处理重试逻辑,不需要手动操作Session:
from google.cloud import spanner import datetime client = spanner.Client() instance = client.instance(instance_id) database = instance.database(database_id) def do_insert(transaction): transaction.insert( table="list", columns=("userid", "code", "starttime"), values=[(id, token, datetime.datetime.utcnow())] ) database.run_in_transaction(do_insert)
注意事项
- 生产环境优先使用
run_in_transaction处理写操作,避免手动管理Session可能出现的资源泄露、事务未正确提交回滚等问题 - 单次只读查询可以直接使用
database.execute_sql()方法,不需要手动创建Session
内容的提问来源于stack exchange,提问作者Aftershock
相关产品推荐
相关产品推荐

