当我尝试执行XA事务时,我的日志中出现以下异常:
javax.transaction.xa.XAException:com.microsoft.sqlserver.jdbc_SQLServerException:无法创建XA控件连接。错误:“对象'xp_sqljdbc_xa_init_ex',数据库'master'架构'dbo'上的EXECUTE权限被拒绝
我按照这些教程Understanding XA Transactions和How to make MSSQL Server XA Datasource Work?进行了操作 在完成第一个教程之后,我还在SSMS中运行了以下命令:
使用主人GO
EXEC sp_addrolemember [SqlJDBCXAUser],'MyUserName'GO
我还要补充说我跑了
使用主GO EXEC sp_grantdbaccess'MyUserName','MyUserName'GO
验证用户是否有权访问主数据库,并且出现“用户已存在于当前数据库中”的错误。
最后,我通过SSMS验证了SqlJDBCXAUser
角色xp_sqljdbc_xa_init_ex
确实已授予EXECUTE。master
。
我使用的数据库显然不是myDBName
而是MyUserName
。
关于此问题,两者之间的唯一关联是myDBName
是master
的所有者,并以Microsoft
中的用户身份存在。
我的服务器在Windows XP SP3上运行(因此第一个教程中提到的修补程序不相关,因为它适用于XP SP2及其下,我知道当我尝试运行此修补程序时)。
有人遇到过这个问题吗?我真的很感激一些线索
谢谢,
Ittai
更新
我再次从SQL Server instance
查看了第一个教程,有两个段落,我不确定它们的含义,它们可能包含解决方案:
在将参与分布式事务的每个SQL Server实例上执行数据库脚本xa_install.sql。此脚本安装由sqljdbc_xa.dll调用的扩展存储过程。这些扩展存储过程实现了Microsoft SQL Server JDBC驱动程序的分布式事务和XA支持。您需要以SQL Server实例的管理员身份运行此脚本。
当他们说master
时,他们是否意味着包含多个数据库的sql server,包括myDBName
和xa_install.sql
(我习惯于oracle术语有点不同)?我按原样运行了use master
脚本,并指出USE master
GO
EXEC sp_grantdbaccess 'shelby', 'shelby'
GO
EXEC sp_addrolemember [SqlJDBCXAUser], 'shelby'
。
这是第二段:
配置用户定义的角色
要授予特定用户使用JDBC驱动程序参与分布式事务的权限,请将用户添加到SqlJDBCXAUser角色。例如,使用以下Transact-SQL代码将名为“shelby”的用户(名为“shelby”的SQL标准登录用户)添加到SqlJDBCXAUser角色:
SqlJDBCXAUser
SQL用户定义的角色是为每个数据库定义。要出于安全目的创建自己的角色,您必须在每个数据库中定义角色,并以每个数据库的方式添加用户。 SqlJDBCXAUser角色在master数据库中严格定义,因为它用于授予对驻留在master中的SQL JDBC扩展存储过程的访问权限。您必须首先授予单个用户访问master的权限,然后在登录master数据库时授予他们访问SqlJDBCXAUser角色的权限。
我不确定,但我认为上面的粗体句子表示只应在master
上定义myDBName
角色,并且应授予访问master
的其他用户访问权限到myDBName
然后添加到角色,以某种方式(不知道如何)在使用{{1}}数据库使用xa包时将启用它们。
更新2: 这是SSMS在SqlJDBCXAUser角色下的存储过程安全设置的屏幕截图
答案 0 :(得分:15)
我们只需要执行以下操作:
USE [master]
GO
CREATE USER [UserName] FOR LOGIN [UserName] WITH DEFAULT_SCHEMA=[dbo]
use [master]
GO
GRANT EXECUTE ON [dbo].[xp_sqljdbc_xa_commit] TO [UserName]
GRANT EXECUTE ON [dbo].[xp_sqljdbc_xa_end] TO [UserName]
GRANT EXECUTE ON [dbo].[xp_sqljdbc_xa_forget] TO [UserName]
GRANT EXECUTE ON [dbo].[xp_sqljdbc_xa_forget_ex] TO [UserName]
GRANT EXECUTE ON [dbo].[xp_sqljdbc_xa_init] TO [UserName]
GRANT EXECUTE ON [dbo].[xp_sqljdbc_xa_init_ex] TO [UserName]
GRANT EXECUTE ON [dbo].[xp_sqljdbc_xa_prepare] TO [UserName]
GRANT EXECUTE ON [dbo].[xp_sqljdbc_xa_prepare_ex] TO [UserName]
GRANT EXECUTE ON [dbo].[xp_sqljdbc_xa_recover] TO [UserName]
GRANT EXECUTE ON [dbo].[xp_sqljdbc_xa_rollback] TO [UserName]
GRANT EXECUTE ON [dbo].[xp_sqljdbc_xa_rollback_ex] TO [UserName]
GRANT EXECUTE ON [dbo].[xp_sqljdbc_xa_start] TO [UserName]
GO
答案 1 :(得分:1)
自从我将Java与SQL服务器一起使用以来已经有一段时间了,但是我发现你的T-SQL中可能没有按照你想要的方式行事。摘录:
use master GO;
EXEC sp_addrolemember [SqlJDBCXAUser], 'MyUserName' GO;
仅将[SqlJDBCXAUser]应用于master数据库中的用户名。如果您的数据库位于另一个实例中,则还必须在那里添加该角色。我假设的另一个是拼写错误('sp_gratdbaccess'应该是'sp_grantdbaccess')。
我假设您必须在所有参与服务器中运行的'xa_install.sql'脚本成功运行,并且您没有收到任何错误消息?检查脚本中它定义的角色,只是为了确保您输入的内容与所需的匹配。
<强>更新强>
只是一些健全性检查:
当微软称之为“实例”时,微软是不明确的,特别是因为它们将它应用于数据库实例(您的数据库)以及SQL Server实例。一台物理服务器可以同时运行多个SQL服务器副本,同时监听不同的端口。其中每个都有自己的Master数据库实例。通过其他语句的上下文(即XA事务支持存在于master数据库中),他们正在讨论您运行的每个SQL Server副本。如果您的应用程序的数据库分布在SQL Server的4个实例(安装)中,则必须在所有四个安装上执行XA安装步骤。
确保角色采用并正确应用于系统的最后一步是使用管理控制台打开master数据库。您希望确保您的用户位于Databases / master / Security / Users文件夹中,并且它已启用SqlJDBCXAUser角色(角色的复选框)。
接下来,转到有抱怨的违规存储过程,并确保所有安全设置都包含SqlJDBCXAUser角色。角色名称不应该区分大小写(因为SQL本身不是),但确保角色案例是相同的情况也不会有什么坏处 - 以防万一。
如果失败,还要在MyDatabase实例中运行'xa_install.sql'脚本。我个人讨厌这种模棱两可,但很可能就是他们的意思。但在此之前,请确保您不需要任何热修复或具有无法正常工作的配置。撤消复杂的SQL脚本所做的事情可能是一个很大的痛苦。这就是我建议最后这样做的原因。