如果在调用commit或rollback之前发生断电,会发生什么情况

本文关键字:断电 什么情况 调用 commit rollback 如果 | 更新日期: 2023-09-27 18:21:06

所以我一直在用以下代码进行测试:

MySqlTransaction trans = null;
                    var con = new MySqlConnection(DBInfo.CON_STRING);
                    try
                    {
                            con.Open();
                            trans = con.BeginTransaction();
                            var query = "INSERT INTO test (num) VALUE (@val1)";
                            var cmd = new MySqlCommand(query, con);
                            cmd.Transaction = trans;
                            cmd.Prepare();
                            cmd.Parameters.AddWithValue("@val1", 0);
                            for (int i = 0; i <= 15; i++)
                            {
                                    cmd.Parameters["@val1"].Value = i;
                                    cmd.ExecuteNonQuery();
                                    if (i == 10)
                                    {
                                            //throw new DivideByZeroException();
                                            MessageBox.Show("pause");
                                    }
                            }
                            trans.Commit();
                    }
                    catch (Exception ex)
                    {
                            MessageBox.Show(ex.StackTrace);
                            try
                            {
                                if (trans != null) trans.Rollback();
                            }
                            catch (Exception ex1)
                            {
                                    MessageBox.Show(ex1.Message);
                            }
                    }
                    finally
                    {
                        con.Close();
                    }

提交和回滚方法。我有一个问题。在for块中,我有一个MessageBox来暂停代码的执行,这样我就可以停止程序来模拟程序的突然执行。问题是查询没有提交,但服务器当时发生了什么?它会自动回滚吗?例如,如果运行程序的PC恰好是服务器,并且停电了,会发生什么?(假设停电发生在for块的执行过程中。

如果在调用commit或rollback之前发生断电,会发生什么情况

当数据库服务器在停电后重新启动时,它会恢复到只包含已提交工作的干净状态。

当数据库客户端在事务处理过程中被切断时,服务器将通过回滚来自动清理事务。

这是一个非常好的问题。MySQL的特点是它与ACID兼容。ACID合规性的字面用例是"如果我们在事务期间拔掉插头会发生什么"。从本质上讲,它可以归结为每个操作都是原子操作,这意味着它要么完成,要么不完成。如果没有,那么保证会保存该事务之前数据库的状态,并且可以在那里继续。如果它完成了,那么您就可以确保,如果您的下一个操作失败,您的当前状态将被保存。

有趣的事实:NoSQL数据库MongoDB的一个主要注意事项是它不符合ACID。因此,如果你有一个更新多个集合的事务,并且你拔出电源插座,那么你的数据库的状态是不确定的(有些可能已经保存,有些可能没有)。

如果你有任何问题,请告诉我!

启动事务时,数据库命令实际上不会更改数据库本身,而是维护用户请求的更改列表。有很多机制可以使这项工作明显透明,但更改存储在日志中。当您进行提交时,它将所有这些事务写入toe数据库的一个块中,因此所有更改都是同时进行的。如果您执行回滚,或者什么都不做(就像停电的情况一样),那么事务日志就会被删除,就好像您一开始从未执行过命令一样。

日志中的延迟和原子提交(意味着它们都被保存在一个快照中,没有人,而不是另一个线程或另一个进程介入)会导致一些奇怪的事情。

例如,如果您有两个到数据库的连接,并执行以下操作:

  1. 打开两个独立的连接,连接1和连接2
  2. 在连接1上开始事务
  3. 使用连接1将数据行R插入表T
  4. 使用连接2,查找表T,您将找不到R行
  5. 在连接1上提交事务
  6. 现在使用连接2,在表T中查找,您将找到行R

这是绝对正确的行为。在第4点,数据仍在连接1的事务日志中,并且尚未写入数据库表,因此在连接2上不可见。只有当连接1的事务日志被提交到数据库时,它在连接2上才可见。