admin 管理员组

文章数量: 886992

数据库误操作

一般指,不小心删除/插入了某个数据,或是当有多个操作同时执行时,因为网络原因或者机器原因,导致整体操作只执行了一半,而数据已失去了逻辑性

例如:

  1. 删除A表数据
  2. 插入B表中与A表关联的某个字段

若此时刚进行完第一个操作,用户关掉网页。那么此时A表数据已经删除,无法进行第二步操作。
如果当用户重新打开网页时,继续从第一步开始执行,则无法进行第一步操作,因为删除操作已经做了。

当我们遇到这种情况下,有几种解决方法。

  1. 软处理
    给A表增加一个status状态,第一步删除时,只将状态值改变,当第二步操作做完,才完全删除该条数据

  2. 将操作顺序置换
    先进行第二步操作,插入完成后再删除

  3. 利用日志回滚数据库数据(太麻烦了,费时间,划不来)

  4. 使用开源框架中的方法
    若运用了开源框架,例如hibernate,即可调用session.rollback()方法,进行对话回滚

  5. SQL事务
    将这两步操作合并成一个整体的操作,即SQL事务

SQL事务

适用场景

适用于一组数据库操作命令。

对这组命令,要么全部执行,要么全部不执行。因此事务是一个不可分割的整体。

事务分类

1 显式事务:用begin transaction明确指定事务的开始。
2 隐性事务:打开隐性事务:set implicit_transactions on,当以隐性事务模式操作时,SQL Servler将在提交或回滚事务后自动启动新事务。无法描述事务的开始,只需要提交或回滚事务。
3 自动提交事务:SQL Server的默认模式,它将每条单独的T-SQL语句视为一个事务。如果成功执行,则自动提交,否则回滚。

事务语法

  • BEGIN TRAN:设置起始点
    数据库会忽略这个起点之后的最终没有提交的所有语句

  • COMMIT TRAN:使事务成为数据库中永久的、不可逆转的一部分
    事务的提交是一个事务的终点

  • ROLLBACK TRAN:本质上说想要忘记它曾经发生过
    ROLLBACK做的事情是回到起点。从关联的BEGIN语句开始发生的任何事情事实上都会被忘记

  • SAVE TRAN:创建一个特定标记符,只允许部分回滚
    保存事务从本质上说就是创建书签(bookmark)。为书签建立一个名称,在建立了”书签”之后,可以在回滚中引用它。创建书签的好处是可以回滚到代码中的特定点上-只要为想要回滚到的那个保存点命名。

事务代码例子

例子中的PO单头和PO单身是两张具有联系的表

     /**作者Jurbo,时间:2016/8/6
             * PO/POline设定页面
             * 删除po单头和对应的PO单身
             **/
            public Boolean deletePo(string po_no)
            {
                string sql = "BEGIN TRAN Tran_deletePo    --开始事务"
                           + "DECLARE @tran_error int;"
                           + "SET @tran_error = 0;"

                       + "BEGIN TRY "
                       + "--删除PO单头"
                       + "delete from wms_po_header "
                       + "where po_no = @po_no; "
                       + "SET @tran_error = @tran_error + @@ERROR;"
                       + "--删除PO单身"
                       + "delete from wms_po_line "
                       + "where po_header_id = (select po_header_id from wms_po_header where po_no=@po_no)"
                       + "END TRY"

                       + "BEGIN CATCH"
                       + "PRINT '出现异常,错误编号:' + convert(varchar,error_number()) + ',错误消息:' + error_message()"
                       + "SET @tran_error = @tran_error + 1"
                       + "END CATCH"

                       + "IF(@tran_error > 0)"
                       + "BEGIN"
                       + "--执行出错,回滚事务"
                       + "ROLLBACK TRAN;"
                       + "PRINT '删除PO/POline失败,取消交易!';"
                       + "END"
                       + "ELSE"
                       + "BEGIN"
                       + "--没有异常,提交事务"
                       + " COMMIT TRAN;"
                       + "PRINT '删除PO/POline成功!';"
                       + "END";

            SqlParameter[] parameters = {
                new SqlParameter("po_no",po_no),
            };

            DB.connect();

            //返回受影响行数InfluenceNum
            int InfluenceNum = DB.delete(sql, parameters);

            if (InfluenceNum > 0)
                return true;
            else
                return false;
        }

MySQL数据恢复

  1. 开启binary log功能
  2. 查看产生的binary log
  3. 利用bin_log恢复数据(date与position)

因为这块没有研究过,故开传送门

MySQL数据恢复--binlog

本文标签: 数据库 事务 操作 数据 SQL