数据库学习(1)事务

1.先举个事务例子,也就是网上经常出现的例子,转账的例子:从账户A转账50元到账户B。这个事务可以定义为:

read(A)
A:=A-50
write(A)
read(B)
B:=B+50
write(B)

其中,read(X)从数据库把数据项X传到read操作的事务的主存缓存区中。write(X)从主缓存中把数据项X存入数据库。
这个操作必须全部执行,或者全部不执行,如果只执行一部分,比如执行了

read(A)
A:=A-50
write(A)

却没执行

read(B)
B:=B+50
write(B)

就会出现A账户的钱变少,B却没有收到转账的情况。所以该事务的步骤不能分割。转账前后A和B的账户总额要不变。而且有人从A中取钱的话不能影响当前事务的执行。这个事务执行完之后,数据就被持久化到数据库中了。

2.关于事务的几个概念。
事务:访问并可能更新各种数据项的一个程序执行单元。
原子性:事务的步骤集合必须作为一个单一的、不可分割的单元出现。要么执行全部内容,要么不执行。如果事务的执行过程中有失败,则要撤销任何对数据库的修改。
不可分割,如果只执行一半,另一半执行错误,那么可能会造成错误。
隔离性:当前事务对数据库的操作不会感知到别的事务的操作,数据库采取特殊的处理来确保事务而不受并发的事务干扰。准确地说,并非要求做到完全无干扰。数据库规定了多种事务隔离界别,不同的隔离级别对应不用的干扰成都,隔离级别越高,数据一致性越好,但并发行越弱。
持久性:一旦事务提交成功后,事务中所有的数据操作都必须被持久化到数据库中。即使在事务提交后,数据库马上崩溃,在数据库重启时,也必须保证能够通过某种机制恢复数据。
一致性:超出了数据完整性约束,如何实现是程序员的职责。这个概念还是比较抽象。
完整性约束:取值非空not null、unique约束,check约束、参照完整性等。
事务状态图

事务状态图.png

活动状态:事务执行时
部分提交状态:最后一条语句执行后
失败状态:执行不能继续后
提交状态:成功完成后
中止状态:事务回滚,数据库已回复事务开始前的状态

事务从活动状态开始,当执行完最后一条语句后进入部分提交状态,然后数据库往磁盘上写入足够的信息,即日志,确保及时出现故障,在数据库系统重启后也能重新执行最后的事务,这条信息写完后,事务就进入了提交状态。

3.mysql中事务:
在mysql数据库中执行下面语句:
begin;
insert into lihong_tbl (NAME,account) VALUES ("悠悠",4000);
insert into lihong_tbl (NAME,account) VALUES ("菲菲",8000);
UPDATE lihong_tbl SET account = 5000 WHERE name = "悠悠";
UPDATE lihong_tbl SET account = 7000 WHERE name = "菲菲";

在没有commit前查询一下。可以看到表中还没有记录。


image.png

然后执行commit;
再查看一下表,可以看到,已经有了刚才的记录。

image.png

使用rollback:
begin;
DELETE from lihong_tbl where id = 8;
ROLLBACK;
数据库并未删除这条记录;

4.在mysql中操作事务:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import pymysql

# 打开数据库连接
db = pymysql.connect("test.com", "testusername", "testpw", "testdb", charset='utf8' )

# 使用cursor()方法获取操作游标
cursor = db.cursor()

# 使用execute方法执行SQL语句
cursor.execute("SELECT VERSION()")

# 使用 fetchone() 方法获取一条数据
data = cursor.fetchone()

print("Database version : %s " % data)

userNameA = "菲菲"
userNameB = "悠悠"
sqlA1 = "select account from lihong_tbl where NAME = " + "\"" + userNameA + "\""
# print(sqlA1)
cursor.execute(sqlA1)
accountA = cursor.fetchone()[0]
print("转账前账户A金额:", accountA)
accountA += 500

sqlA2 = "update lihong_tbl set account =" + str(accountA) + " where NAME = " + "\"" + userNameA + "\""
# print(sqlA2)
cursor.execute(sqlA2)


sqlB1 = "select account from lihong_tbl where NAME = " + "\"" + userNameB + "\""
# print(sqlB1)
cursor.execute(sqlB1)
accountB = cursor.fetchone()[0]
print("转账前账户B金额:", accountB)
accountB = accountB-500

sqlB2 = "update lihong_tbl set account =" + str(accountB) + " where NAME = " + "\"" + userNameB + "\""
# print(sqlA2)
cursor.execute(sqlB2)

db.commit()


cursor.execute(sqlA1)
accountA = cursor.fetchone()[0]
print("commit后账户A金额:", accountA)

cursor.execute(sqlB1)
accountB = cursor.fetchone()[0]
print("commit后账户B金额:", accountB)

# 关闭数据库连接
db.close()

打印结果:
转账前账户A金额: 21000
转账前账户B金额: 6500
commit后账户A金额: 21500
commit后账户B金额: 6000

5.有关数据库的约束:
1)非空约束:用not null约束的字段不能为null值,必须给定具体的数据
2)唯一性约束(unique):unique约束的字段,具有唯一性,不可重复,但可以为null
3)主键约束(primary key):给某个字段添加主键约束之后,该字段不能重复也不能为空,效果和”not null unique”约束相同,但是本质不同。主键约束除了可以做到”not null unique”之外,还会默认添加”索引——index”
4)外键约束(foreign key):若有两个表A、B,id是A的主键,而B中也有id字段,则id就是表B的外键,外键约束主要用来维护两个表之间数据的一致性。

mysql举例操作:

创建表test01,name非空,telephone是主键:
create table test01(
id int(10),
name varchar(32) not null,
telephone varchar(32) primary key,
age int(10)
);

查看列属性:show COLUMNS from test01

改变name属性为unique:ALTER TABLE test01 ADD UNIQUE (name)

添加check约束:ALTER TABLE test01 ADD CHECK (age>0)

创建表test02,外键是test01中的telephone:
create table test02(
gradeid int(10) primary key auto_increment,
grade int(32) not null,
tele varchar(32),
foreign key(tele) references test01(telephone)
);

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容