【问题标题】:Exception with MS-SQL Server,JDBC and XA TransactionsMS-SQL Server、JDBC 和 XA 事务的异常
【发布时间】:2011-05-01 22:14:49
【问题描述】:

当我尝试执行 XA 事务时,我的日志中出现以下异常:

javax.transaction.xa.XAException: com.microsoft.sqlserver.jdbc_SQLServerException: 未能创建 XA 控制连接。错误:“对象'xp_sqljdbc_xa_init_ex',数据库'master'模式'dbo'的EXECUTE权限被拒绝

我遵循了这些教程 Understanding XA TransactionsHow to make MSSQL Server XA Datasource Work? 在遵循第一个教程之后,我还在 SSMS 中运行了以下命令:

使用大师 GO
EXEC sp_addrolemember [SqlJDBCXAUser], 'MyUserName' GO

我还要补充说我跑了

使用 master GO EXEC sp_grantdbaccess 'MyUserName','MyUserName' GO

验证用户是否有权访问主数据库,我收到“用户已存在于当前数据库中”的错误。 最后,我通过 SSMS 验证了角色 SqlJDBCXAUser 确实已授予与 xp_sqljdbc_xa_init_ex 相关的 EXECUTE。
我使用的数据库显然不是master,而是myDBName。 关于这个问题,两者之间唯一的关联是MyUserNamemyDBName 的所有者,并且作为master 中的用户存在。
我的服务器在 Windows XP SP3 上运行(因此第一个教程中提到的修补程序不相关,因为它适用于 XP SP2 及更低版本,我知道我尝试运行该修补程序)。

有人遇到过这个问题吗?我真的很感激一些线索。
谢谢,
伊泰

更新:
我再次查看了来自Microsoft 的第一个教程,其中有两段我不确定它们的含义,它们可能包含解决方案:

在将参与分布式事务的每个 SQL Server 实例上执行数据库脚本 xa_install.sql。此脚本安装由 sqljdbc_xa.dll 调用的扩展存储过程。这些扩展存储过程实现了对 Microsoft SQL Server JDBC 驱动程序的分布式事务和 XA 支持。您需要以 SQL Server 实例的管理员身份运行此脚本。

当他们说SQL Server instance时,他们的意思是包含几个数据库的sql server,包括mastermyDBName(我习惯了oracle术语有点不同)?我运行了xa_install.sql 脚本一次,它显示use master

这是第二段:

配置用户定义的角色
要授予特定用户使用 JDBC 驱动程序参与分布式事务的权限,请将用户添加到 SqlJDBCXAUser 角色。例如,使用以下 Transact-SQL 代码将名为“shelby”的用户(名为“shelby”的 SQL 标准登录用户)添加到 SqlJDBCXAUser 角色:

USE master  
GO  
EXEC sp_grantdbaccess 'shelby', 'shelby'  
GO  
EXEC sp_addrolemember [SqlJDBCXAUser], 'shelby'  

SQL 用户定义角色按数据库定义。为了安全起见,要创建自己的角色,您必须在每个数据库中定义角色,并以每个数据库的方式添加用户。 SqlJDBCXAUser 角色在 master 数据库中严格定义,因为它用于授予对驻留在 master 中的 SQL JDBC 扩展存储过程的访问权限。您必须首先授予个别用户对 master 的访问权限,然后在您登录到 master 数据库时授予他们对 SqlJDBCXAUser 角色的访问权限。

我不确定,但我认为上面加粗的句子说SqlJDBCXAUser 角色应该只在master 上定义,并且访问myDBName 的其他用户应该被授予对master 的访问权限,然后添加到角色中,这将以某种方式(不知道如何)使他们能够在使用 myDBName 数据库时使用 xa 包。

更新 2: 这是 SSMS 中 SqlJDBCXAUser 角色下存储过程的安全设置的屏幕截图

【问题讨论】:

    标签: java sql-server jdbc


    【解决方案1】:

    我们只需要做到以下几点:

    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
    

    【讨论】:

    • 哇!这确实有效!谢谢你。奇怪的是我执行了这些命令的变体(作为 MS 教程的一部分,它们是 xa_install.sl 的一部分),唯一的区别是我授予角色权限并将我的用户添加到角色中。你知道为什么会这样吗?我将不胜感激。
    • 这对我也有用,谢谢! - 我认为微软应该更新他们的文档,使它们更加全面和简单。
    【解决方案2】:

    我已经有一段时间没有将 Java 与 SQL Server 一起使用了,但刚开始我就注意到 T-SQL 中的某些内容可能没有按照您想要的方式运行。 sn-p:

    use master GO;
    EXEC sp_addrolemember [SqlJDBCXAUser], 'MyUserName' GO;
    

    仅将 [SqlJDBCXAUser] 应用于您在主数据库中的用户名。如果您的数据库在另一个实例中,您还必须在那里添加角色。我假设另一个是错字('sp_gratdbaccess' 应该是 'sp_grantdbaccess')。

    我假设您必须在所有参与的服务器中运行的“xa_install.sql”脚本成功运行,并且您没有收到错误消息?检查脚本中定义的角色,以确保您输入的内容与所需内容相符。

    更新:

    只是一些健全性检查:

    Microsoft 在将事物称为“实例”时是模棱两可的,特别是因为它们将其应用于数据库实例(您的数据库)以及 SQL Server 实例。一台物理服务器可以同时运行多个 SQL Server 副本,侦听不同的端口。其中每一个都有自己的主数据库实例。通过其他语句的上下文(即 XA 事务支持存在于主数据库中),它们正在谈论您正在运行的每个 SQL Server 副本。如果您的应用程序数据库分布在 4 个 SQL Server 实例(安装)中,则您必须对所有四个安装执行 XA 安装步骤。

    最后一步是确保角色获得并正确应用到您的系统,使用管理控制台打开主数据库。您要确保您的用户位于 Databases/master/Security/Users 文件夹中,并且启用了 SqlJDBCXAUser 角色(该角色的复选框)。

    接下来,转到抱怨的有问题的存储过程,并确保所有安全设置都包括 SqlJDBCXAUser 角色。角色名称​​不应该区分大小写(因为 SQL 本身不是),但确保角色大小写相同也无妨——以防万一。

    如果失败,请在您的 MyDatabase 实例中运行“xa_install.sql”脚本。我个人讨厌这种模棱两可,但这很可能就是他们的意思。但在您这样做之前,请确保您不需要任何热修复或配置无法正常工作。撤消复杂的 SQL 脚本所做的事情可能会很痛苦。这就是为什么我建议最后这样做。

    【讨论】:

    • 您好,感谢您的评论。笔误确实是笔误。除了脚本(这是一个微软发布的脚本)在添加它们之前尝试删除相关包并因此第一次声明错误之外,没有任何错误,因为没有什么可以删除。关于您在myDBName 中未将角色应用于我的用户名的评论,我在上面添加了信息,这使我认为这是我需要做的。如果您能看一下并给我您的意见,我将不胜感激。
    • 我还更新了我的答案,添加了一些其他的东西来尝试。
    • 操作系统是 Win XP-SP3,因此该修补程序不相关(我之前尝试安装它,但它说它已经安装,因为它是用于 SP2 下的)。我再次验证了该角色出现在 master 的用户中,然后我将在问题中发布 SqlJDBCXAUser 角色相对于存储过程的权限的屏幕截图。如果您同意它看起来合适,我会很遗憾地尝试在 myDB 上运行 xa_install.sql
    • 一切看起来都如说明所示。我有更多关于 SQL Server 实例的信息。我一直在使用自动发现已安装的数据库,并且 SqlServer 的进程 API 列出了服务器名称、实例名称和其他几个参数。在我的开发框中,我有一个 SQL Server 2008 和 2008 Express 的实例。这些是单独的实例。但是,它并不指这些实例上安装的多个数据库。
    • 在您的数据库实例中安装 xa_install.sql 之前,请确保您的用户定义在全局安全/登录中,可以访问您的 myDatabase 实例和主数据库实例。当您查看“用户映射”选项卡时,选择两个数据库并确保在此全局级别应用适当的角色。
    猜你喜欢
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 2011-01-13
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多