Peewee使用之事务

作者: liuchungui | 来源:发表于2018-04-28 23:19 被阅读0次

    Peewee系列:
    Peewee 使用
    Peewee使用之事务
    Peewee批量插入数据
    Peewee 使用(二)——增删改查更详细使用


    上周学习了下基本的Peewee使用,知道了基本的增删改查和建数据库。不过,在项目中同步数据的时候,需要用到事务,于是赶紧补充了官方的Transactions,然后写个总结。

    常用方法

    Peewee实现事务最常用的方法是Database.atomic()方法,非常简单,代码示例如下:

    from xModels import XUser, database
    
    with database.atomic() as transaction:
        XUser.create(phone='184738373833', password='123456')
        XUser.create(phone='184738373833332323232', password='123456')
    

    当事务执行成功之后,它会自动commit(),不需要我们手动调。当事务的代码块中抛出异常时,它会自动调用rollback()

    例如,如果上面的phone设置了长度限制,第二条语句中的phone太长,那么就会抛出异常,然后上面结果是两个用户都不会被添加到数据库中。

    注意:上面database是在xModels文件中MySQLDatabase的一个实例,创建方法如下:

    from peewee import MySQLDatabase
    database = MySQLDatabase('test', **{'charset': 'utf8', 'use_unicode': True, 'host': 'localhost', 'user': 'root', 'password': ''})
    

    除了自动commit()rollback()之外,我们也可以手动调用commit()rollback()方法。

    例如:

    with database.atomic() as transaction:
        XUser.create(phone='199999999999', password='123456')
        transaction.commit()
        XUser.create(phone='188888888888', password='123456')
        transaction.rollback()
    

    结果:手动调用了commit(),phone为199999999999的用户成功添加,而188888888888因为rollback(),不会被添加到数据库中。

    两种使用方式

    Peewee中实现事务有两种使用方式,一种是将atomic当做Context manager使用,另外一种将atomic修饰器使用。

    Context manager

    这种方式,就是我们前面已经使用过了,示例如下:

    from xModels import XUser, database
    
    with database.atomic() as transaction:
        XUser.create(phone='184738373833', password='123456')
        XUser.create(phone='184738373833332323232', password='123456')
    

    修饰器

    @database.atomic()
    def create_user(phone, password):
        XUser.create(phone=phone, password=password)
        raise Exception('just a test')
    
    create_user(phone='184738373833', password='383838')
    

    上面,由于create_user()中抛出了一个异常,修饰器中会执行rollback(),从而导致创建用户失败。

    事务嵌套使用

    Peewee中事务还可以进行嵌套,示例如下:

    with database.atomic() as txn:
        XUser.create(phone='18734738383')
    
        with database.atomic() as nested_txn:
            XUser.create(phone='1883328484')
    

    当上面没有抛出异常时,两个用户同时被添加;当其中任何一条语句抛出异常时,两个用户都不会添加。

    不过,它还是跟非嵌套有些区别的,看下面示例。

    第一种情况,在嵌套事务中执行rollback(),代码如下:

    with database.atomic() as txn:
        XUser.create(phone='188888888')
    
        with database.atomic() as nested_txn:
            XUser.create(phone='199999999')
            nested_txn.rollback()
    

    结果188888888用户被添加,而199999999不会被添加。

    第二种情况,在外层的事务中执行rollback(),代码如下:

    with database.atomic() as txn:
        XUser.create(phone='188888888')
    
        with database.atomic() as nested_txn:
            XUser.create(phone='199999999')
    
        txn.rollback()
    

    结果:两个用户都不会被添加。

    也就是说,外层的rollback()会将嵌套中的事务也回滚,而嵌套中的事务不能回滚外层的内容。当然,这只是我的一个尝试,可能还有其他的不同,还需要再探索。

    全手动实现事务

    全手动实现事务使用的是Database.manual_commit()方法,它也有Context manager修饰器两种方式。

    下面,我们使用Context manager方式来实现前面说的atomic()方法,示例代码如下:

    with database.manual_commit():
        database.begin()  # 开始事务
        try:
            XUser.create(phone='188888888') # 添加用户
        except:
            database.rollback()  # 执行rollback
            raise
        else:
            try:
                database.commit()  # 没有发生异常,执行commit
            except:
                database.rollback() #commit发生异常时,执行rollback
                raise
    

    总结

    Peewee实现事务最简单的方法就是atomic(),它可以使用Context manager修饰器两种方式,它也可以手动调用commit()rollback()

    相关文章

      网友评论

        本文标题:Peewee使用之事务

        本文链接:https://www.haomeiwen.com/subject/apwnlftx.html