2

我创建了一个 Spring Boot 2 (2.1.6.RELEASE) 项目,该项目依赖于 spring-boot-starter-data-jpa 和 spring-boot-starter-jta-bitronix,并为 Mysql DB (8.0.16) 配置了 XA 数据源)。

应用程序属性文件(修剪以与 <> 之间的占位符值相关)包含以下配置:

spring:
  datasource:
    url: jdbc:mysql://<host>:<port>/<dbName>
    username: <username>
    password: <password>
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    database-platform: org.hibernate.dialect.MySQL8Dialect
    hibernate:
      ddl-auto: none
  jta:
    bitronix:
      properties:
        server-id: <serverid>

在启动 Spring Boot 应用程序时,我收到以下错误堆栈跟踪:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unsatisfied dependency expressed through method 'entityManagerFactory' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactoryBuilder' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unsatisfied dependency expressed through method 'entityManagerFactoryBuilder' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaVendorAdapter' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is bitronix.tm.resource.ResourceConfigurationException: cannot create JDBC datasource named dataSource
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactoryBuilder' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unsatisfied dependency expressed through method 'entityManagerFactoryBuilder' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaVendorAdapter' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is bitronix.tm.resource.ResourceConfigurationException: cannot create JDBC datasource named dataSource
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaVendorAdapter' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is bitronix.tm.resource.ResourceConfigurationException: cannot create JDBC datasource named dataSource
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is bitronix.tm.resource.ResourceConfigurationException: cannot create JDBC datasource named dataSource
Caused by: bitronix.tm.resource.ResourceConfigurationException: cannot create JDBC datasource named dataSource
Caused by: bitronix.tm.recovery.RecoveryException: failed recovering resource dataSource
Caused by: com.mysql.cj.jdbc.MysqlXAException: XAER_RMERR: Fatal error occurred in the transaction branch - check your data for consistency
Caused by: java.sql.SQLException: XAER_RMERR: Fatal error occurred in the transaction branch - check your data for consistency
4

1 回答 1

5

免责声明:我正在自我记录自己的问题,希望能帮助其他人,因为令人惊讶的是,这个问题/问题很难解决。

通过验证 github https://github.com/bitronix/btm/issues/100上的 bitronix 问题跟踪器,即使问题已经在没有直接答案的情况下关闭,解决方案也不是很明显。

阅读https://github.com/bitronix/btm/wiki/FAQ上的 bitronix 常见问题解答给出了关于该问题的提示,尽管与 Oracle 有关,它指的是缺少用户权限。

进一步的调查导致了 MySQL 8 文档页面上的权限https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html,特别强调了下一节。

在 MySQL 8.0 之前,任何用户都可以执行 XA RECOVER 语句来发现未完成的准备好的 XA 事务的 XID 值,这可能导致 XA 事务由启动它的用户之外的用户提交或回滚。在 MySQL 8.0 中,XA RECOVER 只允许具有 XA_RECOVER_ADMIN 权限的用户使用,该权限预计只授予需要它的管理用户。例如,XA 应用程序的管理员可能会出现这种情况,如果该应用程序已崩溃并且需要查找由应用程序启动的未完成事务以便回滚它们。此权限要求可防止用户发现除他们自己之外的未完成的已准备 XA 事务的 XID 值。它不会影响 XA 事务的正常提交或回滚,因为启动它的用户知道它的 XID。

因此,我通过 MySQL 中的以下命令(根据需要替换用户名和主机部分)为数据源用户添加了所需的权限。

GRANT XA_RECOVER_ADMIN ON *.* TO 'username'@'%';
FLUSH PRIVILEGES;

通过此更改,spring boot 应用程序启动时没有任何问题。

于 2019-07-01T07:52:20.543 回答