千云物流- 多数据源事务管理

事务管理器

Spring只是个容器,因此它并不做任何事务的具体实现。他只是提供了事务管理的接口PlatformTransactionManager,具体内容由就由各个事务管理器来实现。

Spring提供了许多内置事务管理器实现:

  • DataSourceTransactionManager:位于org.springframework.jdbc.datasource包中,数据源事务管理器,提供对单个javax.sql.DataSource事务管理,用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事务管理;

  • HibernateTransactionManager:位于org.springframework.orm.hibernate3包中,提供对单个org.hibernate.SessionFactory事务支持,用于集成Hibernate框架时的事务管理;该事务管理器只支持Hibernate3+版本,且Spring3.0+版本只支持Hibernate3.2+版本;

  • JpaTransactionManager:位于org.springframework.orm.jpa包中,提供对单个javax.persistence.EntityManagerFactory事务支持,用于集成JPA实现框架时的事务管理;

  • JtaTransactionManager:位于org.springframework.transaction.jta包中,提供对分布式事务管理的支持,并将事务管理委托给Java EE应用服务器事务管理器;这个就是我们需要的。

  • JdoTransactionManager:位于org.springframework.orm.jdo包中,提供对单个javax.jdo.PersistenceManagerFactory事务管理,用于集成JDO框架时的事务管理;

  • OC4JjtaTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对OC4J10.1.3+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持;

  • WebSphereUowTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对WebSphere 6.0+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持;

  • WebLogicJtaTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对WebLogic8.1+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持。

分布式事务样例

在千云物流这边使用在单体应用中,也就是线下软件使用 driud + Atomikos + jpa + jdbcTemplate

  • 数据库准备 atomikos_1,atomikos_2
//为两个库创建操作的表
CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
  • 代码样例
/**
 * @author Janle on 2023/5/5
 */
public class AtomikosExample {
    private static AtomikosDataSourceBean createAtomikosDataSourceBean(String dbName) {
        final DruidXADataSource dataSource = new DruidXADataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:/ip:port/" + dbName);
        dataSource.setUsername("usr");
        dataSource.setPassword("pwd");
        dataSource.setName(dbName);

        AtomikosDataSourceBean sourceBean = new AtomikosDataSourceBean();
        sourceBean.setTestQuery("select 1");
        sourceBean.setXaDataSource(dataSource);
        sourceBean.setUniqueResourceName(dbName);
        sourceBean.setBeanName(dbName);
        return sourceBean;
    }

    public static void main(String[] args) throws SystemException {

        AtomikosDataSourceBean ds1 = createAtomikosDataSourceBean("atomikos_1");
        AtomikosDataSourceBean ds2 = createAtomikosDataSourceBean("atomikos_2");

        JtaTransactionManager transactionManager = transactionManager();
        UserTransaction userTransaction = transactionManager.getUserTransaction();
        try {
            // 开启事务
            userTransaction.begin();
            final JdbcTemplate jdbcTemplate = new JdbcTemplate();
            jdbcTemplate.setDataSource(ds1);

            jdbcTemplate.execute("INSERT into user(name) VALUES ('nihao1')");

			//如果是抛异常就回滚就好了
            //int a=1/0;
            final JdbcTemplate jdbcTemplate2 = new JdbcTemplate();
            jdbcTemplate2.setDataSource(ds2);
            jdbcTemplate2.execute("INSERT into user(name) VALUES ('niyehao')");
            // 两阶段提交
            userTransaction.commit();
        } catch (Exception e) {
            try {
                e.printStackTrace();
                userTransaction.rollback();
            } catch (SystemException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                ds1.close();
                ds2.close();
            } catch (Exception ignore) {
            }
        }
    }

    private static JtaTransactionManager jtaTransactionManager;

    /**
     * 事务管理器
     *
     * @return
     * @throws SystemException
     */
    public static JtaTransactionManager transactionManager() throws SystemException {
        if (null != jtaTransactionManager) {
            return jtaTransactionManager;
        }
        UserTransactionManager userTransactionManager = new UserTransactionManager();
        UserTransaction userTransaction = new UserTransactionImp();
        userTransactionManager.setTransactionTimeout(3000);
        userTransactionManager.setForceShutdown(true);
        jtaTransactionManager = new JtaTransactionManager(userTransaction, userTransactionManager);
        return jtaTransactionManager;
    }
}

常见问题

XAER_RMERR: Fatal error occurred in the transaction branch - check your data for consistency

解决:如果是mysql执行连接账户对应的命令

GRANT XA_RECOVER_ADMIN ON *.* TO 账户@'%' ;

启动出现javax.transaction.xa.XAException: com.microsoft.sqlserver.jdbc.SQLServerException: Failed to create the XA control connection. Error: "Could not find stored procedure ‘master…xp_sqljdbc_xa_init_ex’ 具体查看

https://www.ibm.com/docs/zh/integration-designer/8.5.5?topic=SSTLXK_8.5.5/com.ibm.wbpm.imuc.ebpm.doc/topics/db_xa_nd_win_man.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青0721松

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值