Spring 事务 - 在 Sybase 过程中创建临时 table 时出现 Propagation.REQUIRED 问题

Spring transaction - Propagation.REQUIRED issue when creating temporary table in Sybase procedure

我已经在我的项目中的 DAO 方法上应用了 spring 事务,如下所示

@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'

程序执行精细更新用户table中的记录。但是失败(记录未更新)当我们在过程中创建临时table时,如下所示

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

1) 为什么在过程中创建临时 table 会导致事务(更新操作)失败?
我通过使用 [=35 注释方法解决了这个问题=].
2)为什么Propagation.REQUIRED没有执行程序(有临时table)成功?
3) 在过程中创建临时 table 是否启动隐式事务?

如果没有关于你的过程(w/temp table)如何失败的更多细节,我将猜测这个问题......

  • 创建过程后执行 sp_procxmode / chained,这意味着过程预计 运行 链式事务模式(即,将从事务中调用过程)
  • proc 运行没有#temp table
  • 尝试创建#temp table 时的过程 'fails';我猜 'fails' 意味着你收到一条错误消息......类似于...... "can't create #temp table inside a transaction"
  • 我假设这是 Sybase ASE ...

默认情况下,Sybase ASE 不允许事务内的 DDL;这包括不允许在交易中创建#temp table。

看来您的应用程序可能 运行处于链式事务模式;这意味着所有数据库调用始终在事务内,包括尝试创建#temp table 的存储过程执行,即,proc 试图在事务内创建#temp table .

并且由于事务内部不允许 DDL(例如,#temp table 创建),proc 执行失败(并且 ASE 生成错误,基本上说明您无法创建 #temp table 在交易中)。

查看 Spring 的 NOT_SUPPORTED 选项的文档,(在我看来)这会导致 proc 在外部执行任何事务控制(例如,切换到非链接模式);最终结果是,由于 proc 不在事务内,现在可以创建 #temp table。

我还猜测通过切换 to/from NOT_SUPPORTED 你可能会打破一个更大的交易(不能从这个小您的代码的花絮;您必须查看您的整体事务模型,看看这是好事还是坏事。

如果我的 assumptions/guesses 是正确的,您将不得不(重新)访问您的应用程序的事务模型,着眼于确保您没有发布 DDL(例如,创建一个 #temp table) 在交易中。