当前位置:首页 » 编程语言 » sql事务回滚

sql事务回滚

发布时间: 2022-04-13 00:56:34

Ⅰ 对于已经执行成功的sql命令,如何回滚

当启动Binlog后,事务会产生Binlog Event,这些Event被看做事务数据的一部分。因此要保证事务的Binlog Event和InnoDB引擎中的数据的一致性。所以带Binlog的CrashSafe要求MySQL宕机重启后能够保证:

- 所有已经提交的事务的数据仍然存在。

- 所有没有提交的事务的数据自动回滚。

- 所有已经提交了的事务的Binlog Event也仍然存在。

- 所有没有提交事务没有记录Binlog Event。

这些要求很好理解,如果重启后数据还在,但是Binlog Event没有了,就没办法复制到其他节点上了。如果重启后,数据没了,但是Binlog Event还在,那么不存在的数据就会被复制到其他节点上,从而导致主从的不一致。

为了保证带Binlog的CrashSafe,MySQL内部使用的两阶段提交(Two Phase Commit)。

2 - MySQL的Two Phase Commit(2PC)

在开启Binlog后,MySQL内部会自动将普通事务当做一个XA事务来处理:
- 自动为每个事务分配一个唯一的ID
- COMMIT会被自动的分成Prepare和Commit两个阶段。
- Binlog会被当做事务协调者(Transaction Coordinator),Binlog Event会被当做协调者日志。
想了解2PC,可以参考文档:【https://en.wikipedia.org/wiki/Two-phase_commit_protocol。】

- 分布式事务ID(XID)

使用2PC时,MySQL会自动的为每一个事务分配一个ID,叫XID。XID是唯一的,每个事务的XID都不相同。XID会分别被Binlog和InnoDB记入日志中,供恢复时使用。MySQ内部的XID由三部分组成:

- 前缀部分

前缀部分是字符串"MySQLXid"

- Server ID部分

当前MySQL的server_id
- query_id部分

为了保证XID的的唯一性,数字部分使用了query_id。MySQL内部会自动的为每一个语句分配一个query_id,全局唯一。

参考代码:sql/xa。h的struct xid_t结构。

- 事务的协调者Binlog

Binlog在2PC中充当了事务的协调者(Transaction Coordinator)。由Binlog来通知InnoDB引擎来执行prepare,commit或者rollback的步骤。事务提交的整个过程如下:

1. 协调者准备阶段(Prepare Phase)

告诉引擎做Prepare,InnoDB更改事务状态,并将Redo Log刷入磁盘。

2. 协调者提交阶段(Commit Phase)

2.1 记录协调者日志,即Binlog日志。

2.2 告诉引擎做commit。
注意:记录Binlog是在InnoDB引擎Prepare(即Redo Log写入磁盘)之后,这点至关重要。

在MySQ的代码中将协调者叫做tc_log。在MySQL启动时,tc_log将被初始化为mysql_bin_log对象。参考sql/binlog.cc中的init_server_components():
if (opt_bin_log) tc_log= &mysql_bin_log;

而在事务提交时,会依次执行:
tc_log->prepare();
tc_log->commit();
参考代码:sql/binlog.cc中的ha_commit_trans()。当mysql_bin_log是tc_log时,prepare和commit的代码在sql/binlog.cc中:

MYSQL_BIN_LOG::prepare();
MYSQL_BIN_LOG::commit();

-协调者日志Xid_log_event
作为协调者,Binlog需要将事务的XID记入日志,供恢复时使用。Xid_log_event有以下几个特点:
- 仅记录query_id
因为前缀部分不变,server_id已经记录在Event Header中,Xid_log_event中只记录query_id部分。
- 标志事务的结束

在Binlog中相当于一个事务的COMMIT语句。

一个事务在Binlog中看起来时这样的:
Query_log_event("BEGIN");DML产生的events; Xid_log_event;

- DDL没有BEGIN,也没有Xid_log_event 。
- 仅InnoDB的DML会产生Xid_log_event
因为MyISAM不支持2PC所以不能用Xid_log_event ,但会有COMMIT Event。
Query_log_event("BEGIN");DML产生的events;Query_log_event("COMMIT");

问题:Query_log_event("COMMIT")和Xid_log_event 有不同的影响吗?

- Xid_log_event 中的Xid可以帮助master实现CrashSafe。
- Slave的CrashSafe不依赖Xid_log_event
事务在Slave上重做时,会重新产生XID。所以Slave服务器的CrashSafe并不依赖于Xid_log_event 。Xid_log_event 和Query_log_event("COMMIT"),只是作为事务的结尾,告诉Slave Applier去提交这个事务。因此二者在Slave上的影响是一样的。

3 - 恢复(Recovery)
这个机制是如何保证MySQL的CrashSafe的呢,我们来分析一下。这里我们假设用户设置了以下参数来保证可靠性:

- 恢复前事务的状态
在恢复开始前事务有以下几种状态:
- InnoDB中已经提交
根据前面2PC的过程,可知Binlog中也一定记录了该事务的的Events。所以这种事务是一致的不需要处理。
- InnoDB中是prepared状态,Binlog中有该事务的Events。
需要通知InnoDB提交这些事务。
- InnoDB中是prepared状态,Binlog中没有该事务的Events。
因为Binlog还没记录,需要通知InnoDB回滚这些事务。
- Before InnoDB Prepare
事务可能还没执行完,因此InnoDB中的状态还没有prepare。根据2PC的过程,Binlog中也没有该事务的events。 需要通知InnoDB回滚这些事务。

- 恢复过程
从上面的事务状态可以看出:恢复时事务要提交还是回滚,是由Binlog来决定的。
- 事务的Xid_log_event 存在,就要提交。
- 事务的Xid_log_event 不存在,就要回滚。

恢复的过程非常简单:
- 从Binlog中读出所有的Xid_log_event
- 告诉InnoDB提交这些XID的事务
- InnoDB回滚其它的事务

Ⅱ SQL回滚的作用什么

回滚的作用就是,当有一个SQL语句执行时,条件不符合要求,比如你要插入一个数据,但是插入的数据要有条件的,这时候你就可以用回滚,如果条件成功就COMMIT提交的意思,不然就ROLLBACK回滚,也就是说插入不成功

Ⅲ 高斯误执行sql怎么回滚

回滚指的是在一个SQL事务中,如果遇到执行报错等情况,可以回滚到事务开始的地方。‘
但是如果语句已经执行完毕,那么是没有类似于word中撤销的功能,只能找到语句执行之前数据库的备份,通过关联表查询去找到修改前的记录

Ⅳ SQL语句如何rollback

回滚要放在事务里面进行,才能进行回滚;sql里面的事务使用关键字TransAction
1:可以用try catch捕获
begin try
begin tran
update table set a=1;
commit tran
end Try
begin catch
rollback tran
end catch

2:可以使用error 全局变量
begin tran
update tablename set ad=1111
if @@error<>0 begin rollback end
commit tran

注意:如果一个事务写了 begin trans ,后面一定要跟上 commit tran或 rollback transaction ,否则可能导致被锁

Ⅳ 关于sql中的事务回滚问题 ,就是commit 和 rollback的顺序问题

begin
try

end
try捕获产生的错误
然后在begin
catch

end
catch
块中使用rollback语句让事务回滚
你可以简单地先写个小例子试一下,体会下rollback的用法
比如:
begin
tran
update
table2
set
b=10,c=10
where
a=1
rollback
tran
就会发现数据没有被更新
然后再结合begin
try
end
try
begin
catch
end
catch的用法
就能实现在事务执行过程中出错后回滚的功能
大概的形式就是这样:
begin
tran
begin
try
--做相关操作
--结束的时候如果没有错误则用commit提交事务
commit
tran
end
try
begin
catch
--出现错误的时候会跳转到这里
--用rollback回滚事务
rollback
tran
end
catch

Ⅵ 什么是SQLSERVER事务处理和事务回滚

事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。

当一个事务的某一个操作发生问题时,整个事务可以回滚掉,就像没有做任何操作一样。这就是事务回滚。
如果一个事务的所有操作均成功,则就可以提交事务,保证事务的完整性。

应用程序主要通过指定事务启动和结束的时间来控制事务。

以MS SQL Server的Transac-SQL语言为例,
事务启动:
BEGIN TRAN [ SACTION ] [ transaction_name | @tran_name_variable [ WITH MARK [ 'description' ] ] ]

结束事务
可以使用 COMMIT 或 ROLLBACK 语句结束事务。

1 事务的提交
BEGIN TRANSACTION T1
INSERT tabel1 ...
UPDATE table2 ...
...
/* 当所有成功操作完成,提交事务 */
COMMIT TRAN T1

2 事务的回滚
BEGIN TRANSACTION T1
INSERT tabel1 ...
...
/* 当发生错误或事务被取消, 回滚事务 */
ROLLBACK TRAN T1

Ⅶ sql server事务回滚代码怎么写

事务回滚有几种,下面只是常见的一种

declare@iErrorCountint
set@iErrorCount=0
begintranTran1
insertintot1(Id,c1)values(1,'1')
set@iErrorCount=@iErrorCount+@@error

insertintot1(Id,c1)values('XX2','2')
set@iErrorCount=@iErrorCount+@@error

if@iErrorCount=0
begin
COMMITTRANTran1--执行事务
end
else
begin
ROLLBACKTRANTran1--回滚事务
end

Ⅷ SQL数据库中事务回滚会影响性能吗

首先性能肯定受影响,因为要反向回滚操作。

以sqlserver为例,如果是插入操作,回滚期间锁表,而且一般级别数据库消耗时间接近1:3。如果插入进行了1小时有可能要超过3小时多来完成回滚,此时不要强行关闭数据库或者杀死进程,也为无论如何为了保持acid特性也不会中止回滚只能等。

Ⅸ sql的事务如果失败,但不设置回滚,会发生什么结果

sql的事务是一系列数据库dml操作,如果是中间某个sql执行报错,但是不回滚的话,会导致前面执行成功的语句对数据库造成数据不一致的后果。

热点内容
加密ovpn 发布:2025-05-12 12:01:55 浏览:44
python练手项目 发布:2025-05-12 11:14:07 浏览:122
压缩听算音频 发布:2025-05-12 10:58:12 浏览:801
数据库系统报告 发布:2025-05-12 10:43:17 浏览:603
日产高配有哪些配置 发布:2025-05-12 10:32:16 浏览:475
大众朗逸哪个配置值得入手 发布:2025-05-12 10:31:20 浏览:505
压缩包的后缀 发布:2025-05-12 10:20:35 浏览:944
烟台招聘编程 发布:2025-05-12 10:04:21 浏览:53
sql查询所有表名 发布:2025-05-12 10:01:28 浏览:666
用python编译器的简单代码 发布:2025-05-12 09:48:40 浏览:358