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

时间:2014-09-09 03:19:09

标签: c# mysql visual-studio transactions

所以我一直在测试这段代码:

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区块的过程中。

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

这是一个非常好的问题。 MySQL发生的事情是ACID compliant。 ACID合规性的字面用例是&#34;如果我们在交易期间拔掉插头会发生什么?#34;。基本上它归结为每个操作都是原子的,这意味着它要么完成要么不完成。如果它没有,则保证在该事务之前保存数据库的状态,并且您可以在那里恢复。如果完成,那么您确保如果您的下一次操作失败,您的当前状态将被保存。

有趣的事实:NoSQL数据库MongoDB的一个主要注意事项是它不符合ACID。因此,如果您有一个更新多个集合并且您拉动电源插座的交易,那么您的数据库状态是非确定性的(某些东西可能已经保存,而其他一些可能没有)。

如果您有任何疑问,请与我们联系!

答案 2 :(得分:1)

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

什么是日志中的阻碍,原子提交(意味着它们都被一次性保存而没有一个,而不是另一个线程或其他进程干预)会导致一些奇怪的事情。

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

  1. 打开两个单独的连接,connection1和connection2
  2. 在连接1上开始交易
  3. 使用连接1
  4. 将数据行R插入表T中
  5. 使用连接2,查看表T,您将找不到行R
  6. 在connection1上提交事务
  7. 现在使用连接2,查看表T,现在您将找到行R。
  8. 这是绝对正确的行为。在第4点,数据仍然在connection1的事务日志中,并且尚未写入数据库表,因此在连接2上不可见。只有当connection1的事务日志提交到数据库时,它才会在连接2上可见。 / p>