代码之家  ›  专栏  ›  技术社区  ›  Karthik

Spring事务-传播。在Sybase过程中创建临时表时需要解决的问题

  •  1
  • Karthik  · 技术社区  · 7 年前


    @Transactional(readOnly=false, propagation=Propagation.REQUIRED)
    public String updateUser(Integer userId, String address)
    { 
        //calling sybase procedure to update user address   
    }
    

    Sybase程序

    CREATE PROCEDURE sp_update_user_address
            @user_id      numeric(9,0),
            @address      varchar(500)
    
    AS
    BEGIN
                UPDATE users
                SET address = @address,
                WHERE user_id = @user_id
                and user_status <> 'I'
    END
    go
    EXEC sp_procxmode 'sp_update_user_address', 'chained'
    

    当我们在过程中创建临时表时 如下所示

    //creating temporary table in procedure for some logic
    CREATE TABLE #usertemp
    (
       id int null,
       address varchar(500)
    )
    


    我通过用注释方法解决了这个问题 .
    2) 为什么 没有成功执行过程(具有临时表)?
    3) 在过程内创建临时表是否会启动隐式事务?

    1 回复  |  直到 7 年前
        1
  •  1
  •   markp-fuso    7 年前

    如果没有更多关于进程(带临时表)如何失败的细节,我将猜测这个问题。。。

    • 创建过程后执行 sp_procxmode / chained
    • 在没有#temp表的情况下,过程运行正常
    • 尝试创建#temp表时,过程“失败”;我猜“失败”意味着你会收到一条错误消息。。。类似于。。。“无法在事务内创建#temp表”

    默认情况下,Sybase ASE不允许在事务中使用DDL;这包括不允许在事务中创建#temp表。

    您的应用程序可能正在链式事务模式下运行;这意味着所有数据库调用始终在事务内,包括存储过程执行,该过程试图创建#temp表,即,该过程在事务内尝试创建#temp表。

    由于事务内部不允许DDL(例如#temp表创建),因此过程执行失败(ASE生成一个错误,基本上表明无法在事务中创建#temp表)。

    查看Spring的文档

    我还猜测,通过切换到/从 不支持

    如果我的假设/猜测是正确的,那么您必须(重新)访问应用程序的事务模型,以确保在事务中没有发出DDL(例如,创建#temp表)。