SQLAlchemy会话与事务控制

SQLAlchemy会话与事务控制

       本篇内容为大家提供的是SQLAlchemy基础教程中的SQLAlchemy会话与事务控制,该教程主要介绍了SQLAlchemy会话与事务控制的基本使用、for update、事务嵌套、二段式提交等,详细而全面,感兴趣的同学可以参考学习一下。
 

 

5. SQLAlchemy会话与事务控制

5.1. 基本使用

SQLAlchemy 的 session 是用于管理数据库操作的一个像容器一样的东西. 模型实例对象本身独立存在, 而要让其修改(创建)生效, 则需要把它们加入某个 session . 同时你也可以把模型实例对象从 session 中去除. 被 session 管理的实例对象, 在 session.commit() 时被提交到数据库. 同时 session.rollback() 是回滚变更.

session.flush() 的作用是在事务管理内与数据库发生交互, 对应的实例状态被反映到数据库. 比如自增 ID 被填充上值.

user = User(name=u'名字') 
session.add(user) 
session.commit()


try: 
    user = session.Query(User).first() 
    user.name = u'改名字'
    session.commit() 
except: 
    session.rollback()

5.2. for update

SQLAlchemy 的 Query 支持 select ... for update / share .

session.Query(User).with_for_update().first() 

session.Query(User).with_for_update(read=True).first()

完整形式是:

with_for_update(read=False, nowait=False, of=None)

read:

是标识加互斥锁还是共享锁. 当为 True 时, 即 for share 的语句, 是共享锁. 多个事务可以获取共享锁, 互斥锁只能一个事务获取. 有"多个地方"都希望是"这段时间我获取的数据不能被修改, 我也不会改", 那么只能使用共享锁.

nowait:

其它事务碰到锁, 是否不等待直接"报错".

of:

指明上锁的表, 如果不指明, 则查询中涉及的所有表(行)都会加锁.

5.3. 事务嵌套

SQLAlchemy 中的事务嵌套有两种情况. 一是在 session 中管理的事务, 本身有层次性. 二是 session 和原始的 connection 之间, 是一种层次关系, 在这 session , connection 两个概念之中的事务同样具有这样的层次.

session 中的事务, 可能通过 begin_nested() 方法做 savepoint :

session.add(u1) 
session.add(u2) 

session.begin_nested() 
session.add(u3) 
session.rollback() # rolls back u3, keeps u1 and u2 

session.commit()

或者使用上下文对象:

 for record in records:
     try: 
        with session.begin_nested(): 
            session.merge(record) 
    except: 
        print "Skipped record %s" % record 

 session.commit()

 

嵌套的事务的一个效果, 是最外层事务提交整个变更才会生效.

user = User(name='2')

session.begin_nested()
session.add(user)
session.commit()

session.rollback()

于是, 前面说的第二种情况有一种应用方式, 就是在 connection 上做一个事务, 最终也在 connection 上回滚这个事务, 如果 session 是 bind 到这个连接上的, 那么 session 上所做的更改全部不会生效:

conn = Engine.connect()
session = Session(bind=conn)
trans = conn.begin()

user = User(name='2')
session.begin_nested()
session.add(user)
session.commit()

session.commit()

trans.rollback()

 

在测试中这种方式可能会有用.

5.4. 二段式提交

二段式提交, Two-Phase, 是为解决分布式环境下多点事务控制的一套协议.

与一般事务控制的不同是, 一般事务是 begin, 之后 commit 结束.

而二段式提交的流程上, begin 之后, 是 prepare transaction 'transaction_id' , 这时相关事务数据已经持久化了. 之后, 再在任何时候(哪怕重启服务), 作 commit prepared 'transaction_id' 或者 rollback prepared 'transaction_id' .

从多点事务的控制来看, 应用层要做的事是, 先把任务分发出去, 然后收集"事务准备"的状态(prepare transaction 的结果). 根据收集的结果决定最后是 commit 还是 rollback .

简单来说, 就是事务先保存, 再说提交的事.

SQLAlchemy 中对这个机制的支持, 是在构建会话类是加入 twophase 参数:

 Session = sessionmaker(twophase=True)

 

然后会话类可以根据一些策略, 绑定多个 Engine , 可以是多个数据库连接, 比如:

Session = sessionmaker(twophase=True)
Session.configure(binds={User: Engine, Blog: Engine2})

 

这样, 在获取一个会话实例之后, 就处在二段式提交机制的支持之下, SQLAlchemy 自己会作多点的协调了. 完整的流程:

Engine = create_engine('postgresql://test@localhost:5432/test', echo=True)
Engine2 = create_engine('postgresql://test@localhost:5432/test2', echo=True)

Session = sessionmaker(twophase=True)

Session.configure(binds={User: Engine, Blog: Engine2})
session = Session()

user = User(name=u'名字')
session.add(user)
session.commit()

 

对应的 SQL 大概就是:

begin;
insert into "user" (name) values (?);
prepare transaction 'xx';
commit prepared 'xx';

 

使用时, Postgresql 数据库需要把 max_prepared_transactions 这个配置项的值改成大于 0 


 

有些人一生没有辉煌,并不是因为他们不能辉煌,而是因为他们的头脑中没有闪过辉煌的念头,或者不知道应该如何辉煌。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy是一个Python编程语言下的SQL工具和对象关系映射(ORM)库。它提供了一种方便的方式来与关系型数据库进行交互,如MySQL、PostgreSQL、SQLite等。 使用SQLAlchemy可以实现以下功能: 1. 创建数据库表和模型类:通过定义Python类来映射数据库表,使用SQLAlchemy提供的装饰器和字段类型来定义表结构和字段。 2. 数据库连接和会话管理:SQLAlchemy提供了连接池和会话管理,可以方便地连接到数据库并执行SQL语句。 3. 查询和过滤数据:使用SQLAlchemy的查询API可以方便地执行各种查询操作,如过滤、排序、分组等。 4. 插入、更新和删除数据:通过SQLAlchemy的ORM功能,可以直接操作模型类来插入、更新和删除数据库中的数据。 5. 事务管理:SQLAlchemy提供了事务管理功能,可以确保多个数据库操作的原子性和一致性。 以下是使用SQLAlchemy的基本步骤: 1. 安装SQLAlchemy库:可以使用pip命令进行安装,如`pip install sqlalchemy`。 2. 导入SQLAlchemy模块:在Python代码中导入SQLAlchemy模块,如`import sqlalchemy`。 3. 创建数据库引擎:使用`create_engine`函数创建一个数据库引擎对象,指定数据库的连接信息。 4. 定义模型类:创建Python类来映射数据库表,使用SQLAlchemy提供的装饰器和字段类型来定义表结构和字段。 5. 创建数据库会话:使用`sessionmaker`函数创建一个数据库会话类,用于执行数据库操作。 6. 进行数据库操作:通过创建的会话对象执行数据库操作,如查询、插入、更新和删除等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值