Python操作数据库----模拟银行转账事务
分析、简介
本代码模拟银行转账操作事务;首先要了解数据库事务;然后还要知道怎么样使用事务;
事务
- 访问和更新数据库的一个程序执行单元
- 原子性:事务中包括的诸操作要么做,要么都不做
- 一致性:事务必须使数据库从一致性状态变到另一个一致性状态
- 隔离性:一个事物的执行不能被其他事务干扰
- 持久性:事务一旦提交,它对数据库的改变就是永久性的
开发中怎么使用事务?
- 关闭自动commit:设置conn.autocommit(False)
- 正常结束事务:conn.commit()
- 异常结束事务:conn.rollback()
操作图示
代码开放
案例:模拟银行转账
#coding=utf-8
importsys
import MySQLdb
class TransferMoney(object):
def__init__(self,conn):
self.conn=conn
def transfer(self,source_acctid,target_acctid,money):
try:
self.check_acc_available(source_acctid)
self.check_acc_available(target_acctid)
self.has_enough_money(source_acctid,money)
self.reduce_money(source_acctid,money)
self.add_money(target_acctid,money)
self.conn.commit()
except Exceptionase:
self.conn.rollback()
raisee
def check_acc_available(self,acctid):
cursor=self.conn.cursor()
try:
sql="select*fromaccountwhereacctid=%s"%acctid
cursor.execute(sql)
print"check_acctid_available:"+sql
rs=cursor.fetchall()
if len(rs)!=1:
raise Exception("账号%s不存在"%acctid)
finally:
cursor.close()
def has_enough_money(self,acctid,money):
cursor=self.conn.cursor()
try:
sql="select*fromaccountwhereacctid=%sandmoney>%s"%(acctid,money)
cursor.execute(sql)
print"has_enough_money:"+sql
rs=cursor.fetchall()
if len(rs)!=1:
raiseException("账号%s没有足够的钱"%acctid)
finally:
cursor.close()
def reduce_money(self,acctid,money):
cursor=self.conn.cursor()
try:
sql="updateaccountsetmoney=money-%swhereacctid=%s"%(money,acctid)
cursor.execute(sql)
print"reduce_money:"+sql
rs=cursor.fetchall()
if cursor.rowcount!=1:
raise Exception("账号%s减款失败"%acctid)
finally:
cursor.close()
def add_money(self,acctid,money):
cursor=self.conn.cursor()
try:
sql="updateaccountsetmoney=money+%swhereacctid=%s"%(money,acctid)
cursor.execute(sql)
print "reduce_money:"+sql
rs=cursor.fetchall()
if cursor.rowcount!=1:
raise Exception("账号%s加款失败"%acctid)
finally:
cursor.close()
if__name__=='__main__':
source_acctid=11
target_acctid=12
money=100
conn = MySQLdb.connect(
host='127.0.0.1',
user='root',
passwd='root',
port=3306,
db='imooc'
)
tr_money=TransferMoney(conn)
try:
tr_money.transfer(source_acctid,target_acctid,money)
except Exceptionase:
print"出现问题:"+str(e)
finally:
conn.close()