zoukankan      html  css  js  c++  java
  • ADOConnectoin事务和存储过程中的Begin tran commit

    一直以来我都是在存储过程中使用事务

    create proc usp_proc

    begin

    begin  tran

    .....

    commit

    end

    那么我现在问一个问题,如果在BCB的代码中写这样的代码

    ADOConnection->BeginTrans();

    ADOQuery->SQL->Text = "EXEC usp_proc ";

    //ADOConnection->CommitTrans();  <---注意,我没有提交事务!

    那么存储过程中的事务会提交吗?

    答案是:NO

    --------------------------------------------

    那么现在来回答,为什么存储过程中的事务没有提交。

    本质原因是因为:存储过程中的事务没有命名。

    它只是简单的写了

    BEGIN TRAN

    COMMIT

    于是问题就来,当BCB启动了一个事务的时候,

    执行存储过程 到COMMIT 处,SQL SERVER 到底是提交 BCB代码中 BeginTrans 开启的事务呢,还是 存储过程中的事务呢?

    因为没有显示的指定要提交哪一个事务,所以,SQL SERVER 就提交“上一个”;(类似计数器风格)

    因为BCB 代码中的事务是先开始的,所以SQL SERVER 提交的是 BCB代码中的事务。也就是说,存储过程中的事务并没有提交。

    那么,假设你的存储过程中有一个 TABLOCKX ,会怎样,全部都会阻塞。

    总结一句话,COMMIT 这样的代码,是让SQL SERVER 简单的提交上一个事务而已。

    换句话说,你可以这么写代码(如果你真的这么写,被开除了不要怪我)

    BCB中

    ADOConnectin->BeginTrans();

    然后执行存储过程。

    存储过程中这么写

    create proc usp_proc

    as

    begin

       。。。。do sth

      commit;  <---直接写一个commit,它就会提交BCB代码中的事务。

    end

    那么如何保证存储过程中的事务提交呢?

    答案是给事务命名

    具体的写法看MSDN 的例子,这样,即使BCB得事务没有提交,SQL SERVER 也一定会提交存储过程中的事务的。

    DECLARE @TranName VARCHAR(20);
    SELECT @TranName = 'MyTransaction';
    
    BEGIN TRANSACTION @TranName;
    USE AdventureWorks2008R2;
    DELETE FROM AdventureWorks2008R2.HumanResources.JobCandidate
        WHERE JobCandidateID = 13;
    
    COMMIT TRANSACTION @TranName;
    GO

    再谈谈BCB中能不呢个对事务进行命名。答案是:NO

    再来谈谈事务和会话的关系,一个会话可以有多个事务,比如 先执行事务A,再执行事务B,再提交事务A,然后提交事务B ,

    这其实是事务嵌套,B事务嵌套到A事务中了。

    用一个ADOConnection 做不到,只能借助存储过程来做。切记,BCB的ADOConnection 只能开启一个事务。

  • 相关阅读:
    后端开发者的Vue学习之路(五)
    后端开发者的Vue学习之路(四)
    后端开发者的Vue学习之路(三)
    Vue:如何在地图上添加自定义覆盖物(点)
    后端开发者的Vue学习之路(二)
    后端开发者的Vue学习之路(一)
    字体图标的使用
    Maven的基础了解与使用
    SpringMVC从认识到细化了解
    Mybatis从认识到了解
  • 原文地址:https://www.cnblogs.com/songr/p/5884882.html
Copyright © 2011-2022 走看看