数据库事物
目录:
1.事物
A.事物是什么
B.启动结束事物
C.如何使用
2.事物的特性
3.事物的隔离级别
4.事物隔离级别所存在的问题
5.事物日志
一、事物
因MySQL数据库支持事物的特性,所以重它诞生到现在一直没有被淘汰的原因之一。而mariadb作为mysql 的分支也同时继承了这点。
A.事物是什么
事务是逻辑上的一组操作,组成这组操作的各个单元,要不全都成功要不全都失败,这个特性就是事务。
比如:在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
注意:mysql数据支持事务,但是要求必须是innoDB存储引擎
B.启动结束事物
启动事物:START TRANSACTION
注意:
很多APIs 用于写MYSQL 客户端应用(比如JDBC)提供它们自己的方法用于开始事务可以代替 START TRANSACTION statement
关闭自动提交模式,使用下面的语句:
SET autocommit=0;
在禁用自动提交模式通过设置autocommit variable to zero,
改变事务安全表不是立即永久的,你必须使用COMMIT来存储改变到磁盘或者回滚忽略改变所以:
(1)当AUTOCOMMIT=0时,所有的查询都是在一个事务中,直到显示地执行COMMIT,或者ROLLBACK时,该事务结束。
(2)修改AUTOCOMMIT对非事务型的表(例如,MyISAM),不会有任何影响,相当于一直处于AUTOCOMMIT启用的模式。
(3)一些命令,在执行前会强制执行COMMIT提交当前的事务。例如,使用DDL(数据定义语言)。
(4)MySQL可以通过执行SET TRANSACTION ISOLATION LEVEL命令来设置隔离级别,新的隔离级别会在下一个事务开始时生效。
例如:
# 查看AUTOCOMMIT状态和启用
>SHOW VARIABLES LIKE'AUTO COMMIT';
>SET AUTOCOMMIT =1; # 设置下一个会话的隔离级别为READ COMMITED
>SETTRANSACTIONISOLATIONLEVELREADCOMMITED
结束事物:
事物结束可以分两种,分别为:
(1) COMMIT 提交:提交当前事务,让改变永久
(2) ROLLBACK 回滚:回滚当前事务,取消它的改变
注意:默认情况下, MySQL 运行在autocommit 启用,这意味你 你执行一个语句 更新修改表,MySQL 存储更新到磁盘让它永久,改变不能被回滚。
C.如何使用:
1)在执行sql语句之前,我们要开启事务 start transaction;
2)正常执行我们的sql语句
3)当sql语句执行完毕,存在两种情况:
(1),全都成功,我们要将sql语句对数据库造成的影响提交到数据库中,committ
(2),某些sql语句失败,我们执行rollback(回滚),将对数据库操作赶紧撤销
(注意:mysql数据支持事务,但是要求必须是innoDB存储引擎)
二、事物的特性
一般来说,事务是必须满足4个条件(ACID): Atomicity(原子性)、Consistency(稳定性)、Isolation(隔离性)、Durability(可靠性)
1、事务的原子性:一组事务,要么成功;要么撤回。
2、稳定性 :有非法数据(外键约束之类),事务撤回。
3、隔离性:事务独立运行。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。
4、可靠性:软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改。可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit 选项 决定什么时候吧事务保存到日志里。
二、事物的隔离级别
1)read uncommitted : 读取尚未提交的数据 :哪个问题都不能解决
2)read committed:读取已经提交的数据 :可以解决脏读 ----oracle默认的
3)repeatable read:重读读取:可以解决脏读 和 不可重复读 ---mysql默认的
4)serializable:串行化:可以解决 脏读 不可重复读 和 虚读---相当于锁表
a..查看
SELECT @@tx_isolation
b.设置:
设置mysql的隔离级别:setsession transaction isolation level 设置事务隔离级别
三、.事物隔离级别所存在的问题
1.脏读:
事例:老板要给程序员发工资,程序员的工资是3.6万/月。但是发工资时老板不小心按错了数字,按成3.9万/月,该钱已经打到程序员的户口,但是事务还没有提交,就在这时,程序员去查看自己这个月的工资,发现比往常多了3千元,以为涨工资了非常高兴。但是老板及时发现了不对,马上回滚差点就提交了的事务,将数字改成3.6万再提交。
分析:实际程序员这个月的工资还是3.6万,但是程序员看到的是3.9万。他看到的是老板还没提交事务时的数据。这就是脏读。
2.不可重复读
事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他埋单时(事务开启,不允许其他事务的UPDATE修改操作),收费系统事先检测到他的卡里有3.6万。这个时候他的妻子不能转出金额了。接下来收费系统就可以扣款了。
分析:重复读可以解决不可重复读问题。写到这里,应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。
3幻读
事例:程序员某一天去消费,花了2千元,然后他的妻子去查看他今天的消费记录(全表扫描FTS,妻子事务开启),看到确实是花了2千元,就在这个时候,程序员花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当妻子打印程序员的消费记录清单时(妻子事务提交),发现花了1.2万元,似乎出现了幻觉,这就是幻读。
4.加锁读
Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
示例来自(或想要了解问题和事物的隔离级别关系): http://blog.csdn.net/qq_33290787/article/details/51924963
四、.事物日志
事务日志,可以帮助提高事务的效率。使用事务日志,存储引擎在修改表的数据时,只需要修改其内存拷贝,再把该修改行为记录到硬盘上的事务日志中,而不用每次都将修改的数据本身持久到磁盘。事务日志采用的是追加的方式,因此写日志的操作是磁盘上一小块区域内的顺序I/O,而不是随机I/O,所以快很多。事务日志持久以后,内存中被修改的数据在后台可以慢慢地刷回到磁盘。此方式称之为,预写式日志,修改数据需要写两次磁盘
如果数据的修改已经纪录到事务日志中,但数据本身还没有写回磁盘,此时系统崩溃,存储引擎在重启时,能够自动恢复这部分修改的数据(具体恢复方式则视存储引擎而定)。