一. 准备工作:
1. 安装好mySQL。
2. 安装好mySQLdb模块。
二. 初始化:
1. 先创建一个connect:
conn = MySQLdb.Connect(host = '127.0.0.1',
user = 'root',
passwd = 'root',
port = 3306,
db = 'bank',
charset = 'utf8')
2. 再创建一个cursor:
cursor = conn.cursor()
三. connect对象:
1. cursor():创建一个游标。
2. commit(): 提交。
3. rollback(): 回滚事务。
4. close():关闭。
作用:用来创造cursor,cursor用来进行数据的增,删,查,改。在没有提交commit之前,数据库并不会被修改,此时使用rollback可以返回上一次commit之前的状态。
四. cursor对象:
1. execute(sql):传入一个sql语句用来给数据库执行,执行后的结果存储在缓存区。
对于查找操作来说,直接返回的信息存在缓存区。稍后介绍缓存区信息的取出。
对于增加,删除,修改操作来说,此语句执行之后,数据库中并不会马上被修改,只有在conn.commit()执行之后才会被修改,并且此修改是不可逆的。
2. fetchall():返回缓存区所有信息,返回值是一个元组的元组,元组里面每个元组都是一行的信息。
3.rowcount:一个只读属性,用来表示数据库被修改的行的数量。
4.fetchone():返回缓存区一条信息。返回一个元组存一行信息。
五.说明:
使用innoDB存储引擎,自动提交关闭了之后,才可以进行事务回滚。
六.实战:模拟银行转账:
1. 数据库准备:有一个数据库名叫bank,里面有一个表叫transfer,表有2个字段user_name和money。表的存储引擎是innoDB。
2. 输入汇款方用户名,收款方用户名,钱数。实现转账。
3. 可去除检验用户名的操作,看是否达到事务回滚的效果。
代码:
#coding:utf8
import MySQLdb
class Transfer(object):
def __init__(self, conn):
self.conn = conn
def check_source_id(self, source_account_id):
sql = r"select * from transfer where user_name = '%s'" %source_account_id
self.cursor.execute(sql)
res = self.cursor.fetchall()
if(len(res) != 1):
raise Exception(u"输入账号不存在")
def check_target_id(self, target_account_id):
sql = r"select * from transfer where user_name = '%s'" %target_account_id
self.cursor.execute(sql)
res = self.cursor.fetchall()
if(len(res) != 1):
raise Exception(u"输出账号不存在")
def check_enough_money(self, source_account_id, money):
sql = r"select money from transfer where user_name = '%s'" %source_account_id
self.cursor.execute(sql)
res = self.cursor.fetchall()
if (float(res[0][0]) < money):
raise Exception(u"没有足够的钱")
def add_money(self, account_id, money):
sql = r"update transfer set money = money + %f where user_name = '%s'" %(money, account_id)
self.cursor.execute(sql)
if (self.cursor.rowcount != 1):
raise Exception(u"转账失败")
def tans_money(self, source_account_id, target_account_id, money):
self.cursor = conn.cursor()
try:
self.check_source_id(source_account_id)
self.check_target_id(target_account_id)
self.check_enough_money(source_account_id, money)
self.add_money(source_account_id, -money)
self.add_money(target_account_id, money)
except Exception as e:
raise e
finally:
self.cursor.close()
def show_table(conn):
sql = 'select * from transfer'
cursor = conn.cursor()
cursor.execute(sql)
res = cursor.fetchall()
print "user_name money"
for row in res:
print u"%s %s" %(row[1], row[2])
if __name__ == "__main__":
conn = MySQLdb.Connect(host = '127.0.0.1',
user = 'root',
passwd = 'root',
port = 3306,
db = 'bank',
charset = 'utf8')
conn.autocommit(False)
show_table(conn)
source_account_id = raw_input(u"输入转账用户名:")
target_account_id = raw_input(u"请输入目标用户名:")
money = float(raw_input(u"请输入转账金额:"))
try:
tansfer = Transfer(conn)
tansfer.tans_money(source_account_id, target_account_id, money)
show_table(conn)
conn.commit()
except Exception as e:
print unicode(e)
conn.rollback()
finally:
conn.close()