zoukankan      html  css  js  c++  java
  • mysql 存储过程 事务; mysql的事务中包含一个存储过程

    在asp.net结合mysql的开发中,我平时用到的事务处理是 使用 TransactionOptions  来进行处理

    TransactionOptions transactionOption = new TransactionOptions
                {
                    IsolationLevel = IsolationLevel.ReadCommitted, //设置事务隔离级别
                    Timeout = new TimeSpan(0, 5, 10) // 设置事务超时时间为5分10秒
                };
                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, transactionOption))
                {
                    try
                    {
                        string temp = jkController.Changepoint(mobile, actionType, actionId, point);
    
                        if (temp == "already_login")
                        {
                            throw new MessageJxtException(Message.一天只能获取一次登陆积分);
                        }
                        else if (temp == "already_vote")
                        {
                            throw new MessageJxtException(Message.一个投票只能获取一次投票积分);
                        }
                        else
                        {
                            outPoint = Convert.ToInt32(temp);
                        }
                        scope.Complete(); //提交事务
                    }
                    catch (Exception ex)
                    {
                        throw new MessageJxtException(Message.操作失败本次操作没有执行);
                    }
                }

    这样写了之后,mysql的存储过程里面不需要做特殊处理,你写2个sql语句,任意一个报错,都会在asp.net里面被回滚的(准确的说,是如果没有报错的话,就会和自行到scope.Complete()来执行提交,否则,就不会提交,也就达到了事务)

    但是现在有另外一个客户端是php来编写的,如果让php写来写这样的事务,感觉太麻烦,倒不如我直接去mysql里面写事务好了

    好,今天就来介绍mysql内置的事务处理

    DELIMITER $$
    
    USE `test`$$
    
    DROP PROCEDURE IF EXISTS `test_shiwu`$$
    
    CREATE DEFINER=`root`@`%` PROCEDURE `test_shiwu`(
        p_id INT,
        p_Name VARCHAR(64),
        p_address VARCHAR(64)
        )
    BEGIN
    
    DECLARE t_error VARCHAR(64) DEFAULT 'transaction_ok';  
    
    /** 如果出现sql异常,则将t_error设置为'transaction_error'后继续执行后面的操作 */  
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error='transaction_error'; -- 出错处理  
        /** 显式的开启事务,它开启后,事务会暂时停止自动提交*/  
    START TRANSACTION;  
    
        INSERT INTO `test2`(`address`) VALUES(p_address);      -- 语句1
        INSERT INTO `test1`(`id`,`name`) VALUES(p_id,p_Name);  -- 语句2   这2个语句都可能引起报错
        
    IF t_error = 'transaction_error' THEN
        ROLLBACK;   -- 回滚
        SELECT t_error;  -- 将事务的执行状态返回给被调者
    ELSE
        COMMIT;   -- 提交事务
        SELECT '成功了';
    END IF;
    
    
        
        END$$
    
    DELIMITER ;


    ok 这样就搞定了,asp.net里面的TransactionOptions  也不需要使用了

    我们可以看到在刚才的mysql存储过程里面,是有2个语句,其中的任意一个语句执行报错的话,都会引起回滚操作.

    下面再来一个非常特殊 的情况,我们把刚才的那2个语句,换成另外一个存储过程(因为有时候,我们写sql,不止是2个sql语句,可能是更多,那么我们就需要封装到其他的存储过程里面)

    DELIMITER $$
    
    USE `test`$$
    
    DROP PROCEDURE IF EXISTS `test_shiwu`$$
    
    CREATE DEFINER=`root`@`%` PROCEDURE `test_shiwu`(
    	p_id INT,
    	p_Name VARCHAR(64),
    	p_address VARCHAR(64)
        )
    BEGIN
    
    DECLARE t_error VARCHAR(64) DEFAULT 'transaction_ok';  
    
    /** 如果出现sql异常,则将t_error设置为'transaction_error'后继续执行后面的操作 */  
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error='transaction_error'; -- 出错处理  
        /** 显式的开启事务,它开启后,事务会暂时停止自动提交*/  
    START TRANSACTION;  
    
    	-- INSERT INTO `test2`(`address`) VALUES(p_address);      -- 语句1
    	-- insert into `test1`(`id`,`name`) values(p_id,p_Name);  -- 语句2   这2个语句都可能引起报错
    	
    	CALL test_shiwu_desc(p_id,p_Name,p_address);   -- 这个存储过程里面就只有上面的2个sql语句而已
    	
    IF t_error = 'transaction_error' THEN
        ROLLBACK;   -- 回滚
        SELECT t_error;  -- 将事务的执行状态返回给被调者
    ELSE
        COMMIT;   -- 提交事务
        SELECT '成功了';
    END IF;
    
    
    	
        END$$
    
    DELIMITER ;


    经过测试,在一个存储过程A里面,如果有事务,事务里面又包含另外一个存储过程B的话,是可以执行的.

    也就是说 如果B执行失败,也是会让A进行回滚的.

    最后,我们到asp.net里面,对返回的值进行判断就可以了

    string temp = jkController.Changepoint(mobile, actionType, actionId, point);
                if (temp == "transaction_error")
                {
                    throw new MessageJxtException(Message.操作失败本次操作没有执行);
                }
                else if (temp == "already_login")
                {
                    throw new MessageJxtException(Message.一天只能获取一次登陆积分);
                }
                else if (temp == "already_vote")
                {
                    throw new MessageJxtException(Message.一个投票只能获取一次投票积分);
                }
                else
                {
                    outPoint = Convert.ToInt32(temp);
                }
  • 相关阅读:
    Flex上传文件报“Error #2038”
    AMQ9558
    perl 运算符
    linux gdm 远程桌面访问
    perl 捕获变量
    android apk嵌套 从一个apk启动另外一个apk
    apk调用另一个apk
    ORA-01591 锁被未决分布式事务处理
    jQuery事件控制点击内容下拉
    作业还是作孽?——Leo鉴书79
  • 原文地址:https://www.cnblogs.com/joeylee/p/3684710.html
Copyright © 2011-2022 走看看