MySQL的InnoDB存储引擎支持XA规范。
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.1</version> </dependency> <!--atomikos transaction management--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.21</version> </dependency> 复制代码
spring: application: name: two-data-source datasource: account: url: jdbc:mysql://127.0.0.1:3306/transaction_account?useSSL=false&characterEncoding=UTF-8 username: root password: xxxxx order: url: jdbc:mysql://127.0.0.1:3306/transaction_order?useSSL=false&characterEncoding=UTF-8 username: root password: xxxxx #logging: # level: # root: DEBUG 复制代码
@Configuration @MapperScan(basePackages = {"io.ilss.transaction.twodatasource.dao.account"}, sqlSessionTemplateRef = "accountSqlSessionTemplate") public class AccountConfiguration { @Value("${spring.datasource.account.url}") private String url; @Value("${spring.datasource.account.username}") private String username; @Value("${spring.datasource.account.password}") private String password; @Bean(name = "accountDataSource") public DataSource accountDataSource() { AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean(); DruidXADataSource druidXADataSource = new DruidXADataSource(); druidXADataSource.setUrl(url); druidXADataSource.setUsername(username); druidXADataSource.setPassword(password); druidXADataSource.setName("druidDataSource-account"); atomikosDataSourceBean.setXaDataSource(druidXADataSource); atomikosDataSourceBean.setUniqueResourceName("accountResource"); return atomikosDataSourceBean; } @Bean(name = "accountSqlSessionFactory") public SqlSessionFactory accountSqlSessionFactory(DataSource accountDataSource) throws Exception { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(accountDataSource); factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mappers/account/*.xml")); return factoryBean.getObject(); } @Bean(name = "accountSqlSessionTemplate") @Primary public SqlSessionTemplate accountSqlSessionTemplate(@Qualifier("accountSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } } 复制代码
c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'orderResource': poolSize equals default - this may cause performance problems! com.alibaba.druid.pool.DruidDataSource : {dataSource-1,druidDataSource-order} inited c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'accountResource': poolSize equals default - this may cause performance problems! com.alibaba.druid.pool.DruidDataSource : {dataSource-2,druidDataSource-account} inited c.a.icatch.provider.imp.AssemblerImp : Loaded jar:file:/Users/feng/.m2/repository/com/atomikos/transactions/4.0.6/transactions-4.0.6.jar!/transactions-defaults.properties c.a.icatch.provider.imp.AssemblerImp : Thanks for using Atomikos! Evaluate http://www.atomikos.com/Main/ExtremeTransactions for advanced features and professional support...略 c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.default_max_wait_time_on_shutdown = 9223372036854775807 c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.allow_subtransactions = true c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.recovery_delay = 10000 c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.automatic_resource_registration = true c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.oltp_max_retries = 5 c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.client_demarcation = false c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.threaded_2pc = false c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.serial_jta_transactions = true c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.log_base_dir = /Users/feng/Projects/java/transaction-example/transaction-logs c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.rmi_export_class = none c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.max_actives = 50 c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.checkpoint_interval = 500 c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.enable_logging = true c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.log_base_name = tmlog c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.max_timeout = 300000 c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.trust_client_tm = false c.a.icatch.provider.imp.AssemblerImp : USING: java.naming.factory.initial = com.sun.jndi.rmi.registry.RegistryContextFactory c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.tm_unique_name = 10.11.11.11.tm c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.forget_orphaned_log_entries_delay = 86400000 c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.oltp_retry_interval = 10000 c.a.icatch.provider.imp.AssemblerImp : USING: java.naming.provider.url = rmi://localhost:1099 c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.force_shutdown_on_vm_exit = false c.a.icatch.provider.imp.AssemblerImp : USING: com.atomikos.icatch.default_jta_timeout = 10000 c.a.icatch.provider.imp.AssemblerImp : Using default (local) logging and recovery... c.a.d.xa.XATransactionalResource : orderResource: refreshed XAResource c.a.d.xa.XATransactionalResource : accountResource: refreshed XAResource 复制代码
首先初始化两个Atomikos包裹的Druid的数据源,
然后设置atomikos的参数,都是默认的
最后XAResource刷新
至此,配置完毕,可能有人好奇,JTA的代码一个都没有,因为SpringBoot使用JTA的时候引入的starter做了
@Slf4j @Service public class OrderServiceImpl implements OrderService { @Autowired private OrderInfoDAO orderInfoDAO; @Autowired private AccountDAO accountDAO; @Autowired PlatformTransactionManager transactionManager; @Override @Transactional public String createOrder(OrderInfoDO orderInfoDO) { AccountDO accountDO = accountDAO.selectByPrimaryKey(orderInfoDO.getAccountId()); if (null == accountDO) { log.error("createOrder user is not present, accountId: {}", orderInfoDO.getAccountId()); return "用户不存在!"; } // 用户费用扣除 accountDO.setBalance(accountDO.getBalance().subtract(orderInfoDO.getAmount())); accountDAO.updateByPrimaryKey(accountDO); orderInfoDAO.insertSelective(orderInfoDO); return "成功"; } @Override public String createOrderCode(OrderInfoDO orderInfoDO) { TransactionDefinition transactionDefinition = new DefaultTransactionDefinition(); // 获取事务 开始业务执行 TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition); try { AccountDO accountDO = accountDAO.selectByPrimaryKey(orderInfoDO.getAccountId()); if (null == accountDO) { log.error("createOrder user is not present, accountId: {}", orderInfoDO.getAccountId()); return "用户不存在!"; } // 用户费用扣除 accountDO.setBalance(accountDO.getBalance().subtract(orderInfoDO.getAmount())); accountDAO.updateByPrimaryKey(accountDO); orderInfoDAO.insertSelective(orderInfoDO); error("createOrderCode error"); transactionManager.commit(transaction); return "成功"; } catch (Exception e) { log.error("create order failed, accountId: {}, errMsg: {}", orderInfoDO.getAccountId(), e.getMessage()); transactionManager.rollback(transaction); } return "失败"; } public static void error(String msg) { throw new RuntimeException(msg); } } 复制代码
logging.level.root=DEBUG
如果不设置,你基本看不到什么事务日志。 o.s.web.servlet.DispatcherServlet : GET "/api/order/create", parameters={} s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to io.ilss.transaction.twodatasource.web.OrderController#create() o.s.t.jta.JtaTransactionManager : Creating new transaction with name [io.ilss.transaction.twodatasource.service.impl.OrderServiceImpl.createOrder]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT c.a.i.i.CompositeTransactionManagerImp : createCompositeTransaction ( 10000 ): created new ROOT transaction with id 10.11.11.11.tm157866358813800001 org.mybatis.spring.SqlSessionUtils : Creating a new SqlSession org.mybatis.spring.SqlSessionUtils : Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1502ae81] o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'accountResource': getConnection()... c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'accountResource': init... c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@73c7f762: calling getAutoCommit... c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@73c7f762: calling toString... o.m.s.t.SpringManagedTransaction : JDBC Connection [com.mysql.jdbc.JDBC4Connection@73c7f762] will be managed by Spring i.i.t.t.d.a.A.selectByPrimaryKey : ==> Preparing: select id, nickname, username, `password`, balance, create_time, update_time from account where id = ? c.a.icatch.imp.CompositeTransactionImp : addParticipant ( XAResourceTransaction: 31302E31312E31312E31312E746D313537383636333538383133383030303031:31302E31312E31312E31312E746D31 ) for transaction 10.11.11.11.tm157866358813800001 c.a.datasource.xa.XAResourceTransaction : XAResource.start ( 31302E31312E31312E31312E746D313537383636333538383133383030303031:31302E31312E31312E31312E746D31 , XAResource.TMNOFLAGS ) on resource accountResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@51af9ae0 c.a.icatch.imp.CompositeTransactionImp : registerSynchronization ( com.atomikos.jdbc.AtomikosConnectionProxy$JdbcRequeueSynchronization@853ac8fa ) for transaction 10.11.11.11.tm157866358813800001 c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@73c7f762: calling prepareStatement(select....略 i.i.t.t.d.a.A.selectByPrimaryKey : ==> Parameters: 1(Long) i.i.t.t.d.a.A.selectByPrimaryKey : <== Total: 1 org.mybatis.spring.SqlSessionUtils : Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1502ae81] org.mybatis.spring.SqlSessionUtils : Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1502ae81] from current transaction i.i.t.t.d.a.A.updateByPrimaryKey : ==> Preparing: update account set nickname = ?, username = ?, `password` = ?, balance = ?, create_time = ?, update_time = ? where id = ? c.a.icatch.imp.CompositeTransactionImp : registerSynchronization ( com.atomikos.jdbc.AtomikosConnectionProxy$JdbcRequeueSynchronization@853ac8fa ) for transaction 10.11.11.11.tm157866358813800001 c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@73c7f762: calling prepareStatement(update account i.i.t.t.d.a.A.updateByPrimaryKey : ==> Parameters: 小一(String), xiaoyi(String), 123456(String), 600.00(BigDecimal), 2020-01-09T17:04:28(LocalDateTime), 2020-01-10T16:00:51(LocalDateTime), 1(Long) i.i.t.t.d.a.A.updateByPrimaryKey : <== Updates: 1 org.mybatis.spring.SqlSessionUtils : Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1502ae81] org.mybatis.spring.SqlSessionUtils : Creating a new SqlSession org.mybatis.spring.SqlSessionUtils : Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@20a0ef33] o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'orderResource': getConnection()... c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'orderResource': init... c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@22a176f4: calling getAutoCommit... c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@22a176f4: calling toString... o.m.s.t.SpringManagedTransaction : JDBC Connection [com.mysql.jdbc.JDBC4Connection@22a176f4] will be managed by Spring i.i.t.t.d.o.O.insertSelective : ==> Preparing: insert into order_info ( account_id, completed, order_state, detail, amount, create_time, update_time ) values ( ?, ?, ?, ?, ?, ?, ? ) c.a.icatch.imp.CompositeTransactionImp : addParticipant ( XAResourceTransaction: 31302E31312E31312E31312E746D313537383636333538383133383030303031:31302E31312E31312E31312E746D32 ) for transaction 10.11.11.11.tm157866358813800001 c.a.datasource.xa.XAResourceTransaction : XAResource.start ( 31302E31312E31312E31312E746D313537383636333538383133383030303031:31302E31312E31312E31312E746D32 , XAResource.TMNOFLAGS ) on resource orderResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@473dd4ea c.a.icatch.imp.CompositeTransactionImp : registerSynchronization ( com.atomikos.jdbc.AtomikosConnectionProxy$JdbcRequeueSynchronization@853ac8fa ) for transaction 10.11.11.11.tm157866358813800001 c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@22a176f4: calling prepareStatement(insert into order_info i.i.t.t.d.o.O.insertSelective : ==> Parameters: 1(Long), 0(Integer), 1(Integer), 买衣服(String), 100(BigDecimal), 2020-01-10T21:39:48.134(LocalDateTime), 2020-01-10T21:39:48.134(LocalDateTime) i.i.t.t.d.o.O.insertSelective : <== Updates: 1 org.mybatis.spring.SqlSessionUtils : Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@20a0ef33] org.mybatis.spring.SqlSessionUtils : Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1502ae81] org.mybatis.spring.SqlSessionUtils : Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@20a0ef33] org.mybatis.spring.SqlSessionUtils : Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1502ae81] org.mybatis.spring.SqlSessionUtils : Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1502ae81] org.mybatis.spring.SqlSessionUtils : Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@20a0ef33] org.mybatis.spring.SqlSessionUtils : Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@20a0ef33] c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@73c7f762: close()... c.a.datasource.xa.XAResourceTransaction : XAResource.end ( 31302E31312E31312E31312E746D313537383636333538383133383030303031:31302E31312E31312E31312E746D31 , XAResource.TMSUCCESS ) on resource accountResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@51af9ae0 c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@22a176f4: close()... c.a.datasource.xa.XAResourceTransaction : XAResource.end ( 31302E31312E31312E31312E746D313537383636333538383133383030303031:31302E31312E31312E31312E746D32 , XAResource.TMSUCCESS ) on resource orderResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@473dd4ea o.s.t.jta.JtaTransactionManager : Initiating transaction commit c.a.icatch.imp.CompositeTransactionImp : commit() done (by application) of transaction 10.11.11.11.tm157866358813800001 c.a.datasource.xa.XAResourceTransaction : XAResource.prepare ( 31302E31312E31312E31312E746D313537383636333538383133383030303031:31302E31312E31312E31312E746D31 ) returning OK on resource accountResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@51af9ae0 c.a.datasource.xa.XAResourceTransaction : XAResource.prepare ( 31302E31312E31312E31312E746D313537383636333538383133383030303031:31302E31312E31312E31312E746D32 ) returning OK on resource orderResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@473dd4ea c.a.datasource.xa.XAResourceTransaction : XAResource.commit ( 31302E31312E31312E31312E746D313537383636333538383133383030303031:31302E31312E31312E31312E746D31 , false ) on resource accountResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@51af9ae0 c.a.datasource.xa.XAResourceTransaction : XAResource.commit ( 31302E31312E31312E31312E746D313537383636333538383133383030303031:31302E31312E31312E31312E746D32 , false ) on resource orderResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@473dd4ea m.m.a.RequestResponseBodyMethodProcessor : Using 'text/html', given [text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8] and supported [text/plain, */*, text/plain, */*, application/json, application/*+json, application/json, application/*+json] m.m.a.RequestResponseBodyMethodProcessor : Writing ["成功"] o.s.web.servlet.DispatcherServlet : Completed 200 OK 复制代码
o.s.web.servlet.DispatcherServlet : GET "/api/order/create/code", parameters={} s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to io.ilss.transaction.twodatasource.web.OrderController#createCode() o.s.t.jta.JtaTransactionManager : Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT c.a.i.i.CompositeTransactionManagerImp : createCompositeTransaction ( 10000 ): created new ROOT transaction with id 10.11.11.11.tm157866420875900002 org.mybatis.spring.SqlSessionUtils : Creating a new SqlSession org.mybatis.spring.SqlSessionUtils : Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48f4fdff] o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'accountResource': getConnection()... c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'accountResource': init... c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@73c7f762: calling getAutoCommit... c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@73c7f762: calling toString... o.m.s.t.SpringManagedTransaction : JDBC Connection [com.mysql.jdbc.JDBC4Connection@73c7f762] will be managed by Spring i.i.t.t.d.a.A.selectByPrimaryKey : ==> Preparing: select id, nickname, username, `password`, balance, create_time, update_time from account where id = ? c.a.icatch.imp.CompositeTransactionImp : addParticipant ( XAResourceTransaction: 31302E31312E31312E31312E746D313537383636343230383735393030303032:31302E31312E31312E31312E746D33 ) for transaction 10.11.11.11.tm157866420875900002 c.a.datasource.xa.XAResourceTransaction : XAResource.start ( 31302E31312E31312E31312E746D313537383636343230383735393030303032:31302E31312E31312E31312E746D33 , XAResource.TMNOFLAGS ) on resource accountResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@51af9ae0 c.a.icatch.imp.CompositeTransactionImp : registerSynchronization ( com.atomikos.jdbc.AtomikosConnectionProxy$JdbcRequeueSynchronization@6bb297a ) for transaction 10.11.11.11.tm157866420875900002 c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@73c7f762: calling prepareStatement(select....略 i.i.t.t.d.a.A.selectByPrimaryKey : ==> Parameters: 1(Long) i.i.t.t.d.a.A.selectByPrimaryKey : <== Total: 1 org.mybatis.spring.SqlSessionUtils : Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48f4fdff] org.mybatis.spring.SqlSessionUtils : Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48f4fdff] from current transaction i.i.t.t.d.a.A.updateByPrimaryKey : ==> Preparing: update account set nickname = ?, username = ?, `password` = ?, balance = ?, create_time = ?, update_time = ? where id = ? c.a.icatch.imp.CompositeTransactionImp : registerSynchronization ( com.atomikos.jdbc.AtomikosConnectionProxy$JdbcRequeueSynchronization@6bb297a ) for transaction 10.11.11.11.tm157866420875900002 c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@73c7f762: calling prepareStatement(update account... 略 i.i.t.t.d.a.A.updateByPrimaryKey : ==> Parameters: 小一(String), xiaoyi(String), 123456(String), 500.00(BigDecimal), 2020-01-09T17:04:28(LocalDateTime), 2020-01-10T16:00:51(LocalDateTime), 1(Long) i.i.t.t.d.a.A.updateByPrimaryKey : <== Updates: 1 org.mybatis.spring.SqlSessionUtils : Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48f4fdff] org.mybatis.spring.SqlSessionUtils : Creating a new SqlSession org.mybatis.spring.SqlSessionUtils : Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1901cd8f] o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'orderResource': getConnection()... c.atomikos.jdbc.AbstractDataSourceBean : AtomikosDataSoureBean 'orderResource': init... c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@22a176f4: calling getAutoCommit... c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@22a176f4: calling toString... o.m.s.t.SpringManagedTransaction : JDBC Connection [com.mysql.jdbc.JDBC4Connection@22a176f4] will be managed by Spring i.i.t.t.d.o.O.insertSelective : ==> Preparing: insert into order_info ( account_id, completed, order_state, detail, amount, create_time, update_time ) values ( ?, ?, ?, ?, ?, ?, ? ) c.a.icatch.imp.CompositeTransactionImp : addParticipant ( XAResourceTransaction: 31302E31312E31312E31312E746D313537383636343230383735393030303032:31302E31312E31312E31312E746D34 ) for transaction 10.11.11.11.tm157866420875900002 c.a.datasource.xa.XAResourceTransaction : XAResource.start ( 31302E31312E31312E31312E746D313537383636343230383735393030303032:31302E31312E31312E31312E746D34 , XAResource.TMNOFLAGS ) on resource orderResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@473dd4ea c.a.icatch.imp.CompositeTransactionImp : registerSynchronization ( com.atomikos.jdbc.AtomikosConnectionProxy$JdbcRequeueSynchronization@6bb297a ) for transaction 10.11.11.11.tm157866420875900002 c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@22a176f4: calling prepareStatement(insert into order_info...略 i.i.t.t.d.o.O.insertSelective : ==> Parameters: 1(Long), 0(Integer), 1(Integer), 买衣服(String), 100(BigDecimal), 2020-01-10T21:50:08.759(LocalDateTime), 2020-01-10T21:50:08.759(LocalDateTime) i.i.t.t.d.o.O.insertSelective : <== Updates: 1 org.mybatis.spring.SqlSessionUtils : Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1901cd8f] i.i.t.t.service.impl.OrderServiceImpl : create order failed, accountId: 1, errMsg: createOrderCode error org.mybatis.spring.SqlSessionUtils : Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48f4fdff] org.mybatis.spring.SqlSessionUtils : Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48f4fdff] org.mybatis.spring.SqlSessionUtils : Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1901cd8f] org.mybatis.spring.SqlSessionUtils : Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1901cd8f] c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@73c7f762: close()... c.a.datasource.xa.XAResourceTransaction : XAResource.end ( 31302E31312E31312E31312E746D313537383636343230383735393030303032:31302E31312E31312E31312E746D33 , XAResource.TMSUCCESS ) on resource accountResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@51af9ae0 c.atomikos.jdbc.AtomikosConnectionProxy : atomikos connection proxy for com.mysql.jdbc.JDBC4Connection@22a176f4: close()... c.a.datasource.xa.XAResourceTransaction : XAResource.end ( 31302E31312E31312E31312E746D313537383636343230383735393030303032:31302E31312E31312E31312E746D34 , XAResource.TMSUCCESS ) on resource orderResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@473dd4ea o.s.t.jta.JtaTransactionManager : Initiating transaction rollback c.a.datasource.xa.XAResourceTransaction : XAResource.rollback ( 31302E31312E31312E31312E746D313537383636343230383735393030303032:31302E31312E31312E31312E746D33 ) on resource accountResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@51af9ae0 c.a.datasource.xa.XAResourceTransaction : XAResource.rollback ( 31302E31312E31312E31312E746D313537383636343230383735393030303032:31302E31312E31312E31312E746D34 ) on resource orderResource represented by XAResource instance com.mysql.jdbc.jdbc2.optional.MysqlXAConnection@473dd4ea c.a.icatch.imp.CompositeTransactionImp : rollback() done of transaction 10.11.11.11.tm157866420875900002 c.a.icatch.imp.CompositeTransactionImp : rollback() done of transaction 10.11.11.11.tm157866420875900002 m.m.a.RequestResponseBodyMethodProcessor : Using 'text/html', given [text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8] and supported [text/plain, */*, text/plain, */*, application/json, application/*+json, application/json, application/*+json] m.m.a.RequestResponseBodyMethodProcessor : Writing ["失败"] o.s.web.servlet.DispatcherServlet : Completed 200 OK 复制代码