gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 06:30:12 24 4
gpt4 key购买 nike

我在项目中的 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'

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

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

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

最佳答案

如果没有有关您的过程(带临时表)如何失败的更多详细信息,我将猜测问题......

  • 创建过程后,您执行sp_procxmode/chained,这意味着过程预计以链式事务模式运行(即,将从事务内调用过程)
  • 在没有#temp 表的情况下,proc 运行正常
  • 尝试创建#temp 表时过程“失败”;我猜“失败”意味着您收到错误消息...类似...“无法在事务内创建#temp 表”
  • 我假设这是 Sybase ASE ...

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

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

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

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

我还猜测,通过切换到/从 NOT_SUPPORTED 切换,您可能会破坏一个更大的事务(无法从代码的这一小段内容中真正看出;您必须查看查看您的整体交易模型,看看这是好事还是坏事)。

如果我的假设/猜测是正确的,您将必须(重新)访问您的应用程序的事务模型,并着眼于确保您在事务内部时没有发出 DDL(例如,创建 #temp 表)。

关于java - Spring 事务 - 在 Sybase 过程中创建临时表时出现 Propagation.REQUIRED 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46315639/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com