事务控制语言(DTL)
mysql数据事务控制语言DTL(Data Transaction Language) 。
什么是事务
通常,一个句子用一个分号(;)结束并执行。这个一次性执行的过程可以称为一件事。
简单来说,一个sql句子,是事务。
数据库(包括mysql数据库中的事务是一种内部机制,可以将多句的执行视为一句。
也就是说,事务是一种机制,可以保证多句一次性执行或一句都不执行。
将一系列的sql语句作为一句执行的机制——这一系列语句要么全部成功执行,要么一个都不执行。
为什么需要事务?
在实际应用中,经验中的一个操作往往对应于数据库(表)中的两个或两个以上的操作。此时,这两个操作应该是完整的。
比如网银汇款,其实就是把一个储户的钱减少一个数字,再把另一个储户的钱增加一个数字。
如果前者只完成,后者会因为某种原因出错。
| id | 账户名 | 存款 |
|---|---|---|
| 1 | test1 | 1000 |
| 2 | test2 | 5000 |
| 3 | test3 | 3000 |
例如现在,test1向test2银行转账4000:
第一步: update cunkuan set 存款=存款-4000 where id=1;
第一步完成,突然断电!第二步还没来得及做。
第二步: update cunkuan set 存款=存款 4000 where id=2;
如果没有事情,这种事情可能会发生。如果有事情,可以避免。
事务可以看作是一个容器,将多个句子放入容器中。最后,只要命令行决定所有句子是否执行。
事务的特点
原子性:
一个事务中的所有句子都要做到:要么全部做,要么一个都不做;
一致性:
保持数据的逻辑合理性。例如,当一种商品出库时,不仅要减少商品库中的商品数量,还要在相应用户的购物车中添加1;
隔离性:
若多个事务同时并发执行,但每个事务就像独立执行一样。
持久性:
成功执行事务应该是硬盘数据的明确变化(而不仅仅是内存中的变化)。
事务模式
事务模式:是否将每个执行句视为一个事务。
mysql默认安装后,其事务模式为:一个句子(以句子结束符为标志)作为事务执行。
查看模式:
show variables like '%autocommit%'; 将autocommit如果设置为0,则必须使用所有句子commit正式生效后:
set autocommit = 0; 比如:
原来数据:
执行插入:
结果:
现修改为:事务需要认可模式:
set autocommit = 0; # false,关闭这种模式,也就是说,此时不再是一个句子和一个事务。 # 结果是:必须使用commit句子能生效。 然后插入:
刷新: 可见,没有变化。
然后再执行commit:
再刷新:
注意:autocommit设置值只会影响每个句子的默认行为(自动提交或等待)commit提交)。
不管autocommit的值是什么(1,0),仍然可以使用事务的完整流程模式来实现事务。
实现事务的基本过程
基本流程:
-
声明事务开始:
start transaction; # 或: begin; -
设置多个要执行的具体设置sql例如:insert, update, delete, select等等,其实就是执行,但这些执行的句子并不生效——只是内存状态下的执行,而不是物理状态的执行。
-
判断上述句子是否错误(cmd直接观察是否出错,php语句在程序中的返回结果是否为false或者使用 mysql_error()函数判断是否有错误)
这些句子是否需要执行:
if(判断是否有错误){ // 执行-实施物理变化-即生效。 // 如果没有错误,执行commit语句 commit; } else { // 回滚-不执行任何句子。 // 否则执行rollback语句 rollback; }
以下是利用事务完全实现转账(假设为cmd模式):
start transaction; # 第一步: update cunkuan set 存款=存款-4000 where id=1; # 第一步完成后,突然电? # 第二步: update cunkuan set 存款=存款 4000 where id=2; # 如果这两个句子都没有错,可以: commit; # 若有错误,则可: rollback; 示例: