事务是保证数据一致性的保障,很多时候我们都须要用到事务来处理一些复杂的逻辑,没有事务的情况数据就会出现差错,但有时候你的事情就不会成功,却不知道原因,接下来我把一些问题进行简单的分析
数据库引擎
首先你的数据库要支持事务处理,如果这都不能保证,事务也就不存在了,因此在创建表的时候就要指定数据库引擎,例如:
CREATE TABLE `tpf_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
其中InnoDB就是支持事务的数据库引擎,事多相关知道可以看这篇“mysql数据库引擎”
事务处理流程
事务的通常的处理流程是这样的
1、开启事务
2、逻辑处理(数据库相关处理)
3、提交事务
4、回滚事务
直接代码的时候是要加上try{}catch{}处理的,例如:
Db::startTrans(); // 开启事务
try{
Db::execute("INSERT INTO `".DB_PREFIX."test` (`username`) VALUES ('aaa');");
Db::execute("INSERT INTO `".DB_PREFIX."test` (`username`) VALUES ('bbb');");
Db::commit(); // 放后面统一提交
}catch(\Exception $e){
Db::rollback(); // 出现异常后回滚
throw new \Exception($e->getMessage(), 1);
}
像这种如果出现数据处理问题,就会回滚,但是如果像下面这样的呢
Db::startTrans();
try{
Db::execute("DROP TABLE `".DB_PREFIX."test`;");
Db::execute("INSERT INTO `".DB_PREFIX."test` (`username`) VALUES ('aaa');");
Db::execute("INSERT INTO `".DB_PREFIX."test` (`username`) VALUES ('$bbb');");
Db::commit();
}catch(\Exception $e){
Db::rollback();
throw new \Exception($e->getMessage(), 1);
}
注意看里面有一个$bbb变量是存在的,肯定会出错,但我前面是删除表,后面再插入,数据会不会回滚呢,遗憾的是报的不是变量$bbb未定义,而是表test不存在,说明删除已经成功了,什么原因呢???
原因就是DROP在进行处理的时候是即时提交的,也就是直接commit,只要commit成功后的操作都是不能再回滚的了,事务将失效,那么哪些会有这种情况呢???
实际上DDL(Data Definition Language 数据定义语言)的所有操作都是即时提交的,例如像下面的这么一些命令
create table 创建表
alter table 修改表
drop table 删除表
truncate table 删除表中所有行
create index 创建索引
drop index 删除索引
总的来说,只要是提交后,进行的事务回滚都将失效
总结
我们进行事务处理通过都只是针对DML(data manipulation language)数据操纵语言进行处理,也就是我们常用的UPDATE、INSERT、DELETE,因为以后再用事务的时候不成功就要好好分析原因了
文章来源tpframe,转载请指明出处!