peewee 事物 回滚

作者 夜狼荼 2020年03月02日 11:54 阅读 1473

peewee 事物 回滚

在这之前,我们要还是需要看下peewee关于事务方面的代码。 我们可以发现MySQLDatabase默认就把for_update配置为True,另外父类Database有autocommit参数,用来开启事务。

官方文档: http://docs.peewee-orm.com/en/latest/peewee/api.html#Database.atomic

官方文档注释

class MySQLDatabase(Database):
    #Database subclass that works with either “MySQLdb” or “pymysql”.
    commit_select = True
    compound_operations = ['UNION']
    for_update = True
    subquery_delete_same_table = False
 
 
class Database():
    def __init__(self, database, threadlocals=True, autocommit=True,
                 fields=None, ops=None, autorollback=False, use_speedups=True,
                 **connect_kwargs):
        ...
    def begin(self):
        pass
 
    def commit(self):  #提交事务
        self.get_conn().commit()
 
    def rollback(self): # 回滚
        self.get_conn().rollback()
 
    def set_autocommit(self, autocommit):  #设置autocommit状态,值为False,True
        self.__local.autocommit = autocommit
 
    def get_autocommit(self):   #获取autocommit状态.
        if self.__local.autocommit is None:
            self.set_autocommit(self.autocommit)
        return self.__local.autocommit
 
class _atomic(_callable_context_manager):   # 装饰器的模式处理事务逻辑. def __init__(self, db):
        self.db = db
 
    def __enter__(self):
        if self.db.transaction_depth() == 0:
            self._helper = self.db.transaction()
        else:
            self._helper = self.db.savepoint()
        return self._helper.__enter__()
 
    def __exit__(self, exc_type, exc_val, exc_tb):
        return self._helper.__exit__(exc_type, exc_val, exc_tb)
 
class transaction(_callable_context_manager):
    def __init__(self, db):
        self.db = db
 
    def _begin(self):
        self.db.begin()
 
    def commit(self, begin=True):
        self.db.commit()
        if begin:
            self._begin()
 
    def rollback(self, begin=True):
        self.db.rollback()
        if begin:
            self._begin()
 
    def __enter__(self):
        self._orig = self.db.get_autocommit()
        self.db.set_autocommit(False)
        if self.db.transaction_depth() == 0:
            self._begin()
        self.db.push_transaction(self)
        return self
 
    def __exit__(self, exc_type, exc_val, exc_tb):
        try:
            if exc_type:
                self.rollback(False)
            elif self.db.transaction_depth() == 1:
                try:
                    self.commit(False)
                except:
                    self.rollback(False)
                    raise
        finally:
            self.db.set_autocommit(self._orig)
            self.db.pop_transaction()

4中用法例子

实例1,2是使用 peewee封装的db.atomic()原子性,3,4是利用关闭自动提交和手动回滚来保证事物的原子性;

from peewee import *


db = MySQLDatabase(host='123.57.229.66', user='root', passwd='password', database='czj', charset='utf8')

class tb_users(Model):
    id = PrimaryKeyField()  # 主键
    mobile = CharField(unique=True, max_length=64, null=False)  # 注册手机号/openid
    password = CharField(max_length=32)  # 密码
    truename = CharField(max_length=32)  # 真实姓名/nickname

    class Meta:
        database = db

# 一
def one():
    try:
        with db.atomic():
            tb_users.create(mobile='120', password='120', truename='120')
            raise 'haha'
        print 'Success'
    except IntegrityError:
        print 'Failure: %s is already in use.' % username

# 二
@db.atomic()
def create_user():
    tb_users.create(mobile='120', password='120', truename='120')
    raise 'haha'

def two():
    create_user()


# 三
def three():
    db.set_autocommit(False)
    db.begin()
    try:
        tb_users.create(mobile='120', password='120', truename='120')
        raise 'haha'
    except:
        db.rollback()
        raise
    else:
        try:
            db.commit()
        except:
            db.rollback()
            raise
    finally:
        db.set_autocommit(True)

# 四
def four():
    db.set_autocommit(False)
    db.begin()
    tb_users.create(mobile='120', password='120', truename='120')
    db.rollback()
    db.commit()
    db.set_autocommit(True)

发表评论