1. 什么是事务
事务是一个序列操作,其中的操作要么都执行,要么都不执行
2. 事务的特性
3. 看看事务是如何工作的
本地环境模拟,准备两张表:
CREATE TABLE `user_log` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
`user_id` int(11) unsigned NOT NULL COMMENT '用户ID',
`scores` int(11) NOT NULL COMMENT '积分',
`token` varchar(255) NOT NULL COMMENT '唯一性token',
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
`is_delete` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标识',
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_token` (`token`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户记录表'
CREATE TABLE `user_account` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
`scores` int(11) NOT NULL COMMENT '积分',
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
`is_delete` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标识',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户账户表'
客户端1和客户端2同时打开数据库,开启事务。测试一下几种场景:
步骤2.客户端1写入A,B两条记录,不提交事务;客户端2写入B记录
查看进行中的事务:SELECT * FROM information_schema.INNODB_TRX;
查看锁定等待的请求:select * from INNODB_LOCK_WAITS;
步骤3.客户端1进行rollback操作,看看客户端2的数据情况
数据记录id发生了什么变化
客户端2的记录提交成功了么
4. 思考
数据库事务作为一个最小单元,只能全部成功或者全部失败。失败后数据库操作会回滚,但并不意味着毫无痕迹(比如自增主键的ID变化)。
数据库回滚本质上是undo log,把事务过程中的语句对等的保留了undo log,回滚时反向操作把数据恢复原样。但是,如果数据库事务中有其他不能回滚的操作(比如第三方接口调用),那就会发生业务不一致的问题。
数据库的隔离性保证了多个事务在并发执行时不相互影响,但并不是说完全感知不到其他事务的存在(比如主键冲突检查,多个事务有数据可能发生冲突时会有等待的过程INNODB_LOCK_WAITS)。
事务一旦提交后,数据就持久化了,即便再进行回滚也不会影响事务的数据。在开发过程中,要尽量避免commit事件后的逻辑抛异常,否则catch住异常进行回滚就会发生事务不匹配的问题(transaction not match)
参考文档: