MS-SQL Server,JDBC和XA事务的异常

时间:2010-10-28 14:29:02

标签: java sql-server jdbc

当我尝试执行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

我还要补充说我跑了

  

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

验证用户是否有权访问主数据库,并且出现“用户已存在于当前数据库中”的错误。 最后,我通过SSMS验证了SqlJDBCXAUser角色xp_sqljdbc_xa_init_ex确实已授予EXECUTE。master。 我使用的数据库显然不是myDBName而是MyUserName。 关于此问题,两者之间的唯一关联是myDBNamemaster的所有者,并以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,包括myDBNamexa_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角色下的存储过程安全设置的屏幕截图 alt text

2 个答案:

答案 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脚本所做的事情可能是一个很大的痛苦。这就是我建议最后这样做的原因。