首頁/ 汽車/ 正文

SpringBoot整合分散式事務Seata

一、上一篇seata的整合

上一篇seata的版本是0。7。0,因為與匯入的依賴io。seata版本不同導致整合失敗,所以換為seata1。4。0版本號

關於seata的整合注意配置,注意選擇的driverClassName以及store。mode修改為db

SpringBoot整合分散式事務Seata

3。在需要開啟分散式事務的業務庫中建立undo_log表

CREATE TABLE `undo_log` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`branch_id` bigint(20) NOT NULL,`xid` varchar(100) NOT NULL,`context` varchar(128) NOT NULL,`rollback_info` longblob NOT NULL,`log_status` int(11) NOT NULL,`log_created` datetime NOT NULL,`log_modified` datetime NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

注意版本、注意版本、注意版本

二、匯入相關seata的相關依賴

io。seata seata-spring-boot-starter 1。4。0 com。alibaba。nacos nacos-client 1。1。4

SpringBoot整合分散式事務Seata

三、啟動seata

1.如果版本不是1.4.0會報錯,即依賴與seata下載的服務版本不一致

Exception in thread

“main”

io。seata。common。exception。FrameworkException: No available service

SpringBoot整合分散式事務Seata

2.選擇一致的版本

SpringBoot整合分散式事務Seata

3.配置seata的配置資訊

seata。enabled=trueseata。enableAutoDataSourceProxy=false#seata註冊的服務名稱seata。application-id=test1#此處配置自定義的seata事務分組名稱seata。tx-service-group=my_test_tx_groupseata。service。vgroup-mapping。my_test_tx_group=default#這個屬性的值設定為true,則可以正常啟動該Seata專案,但如果屬性值為true則表示不開啟全域性事務,而我要實現全域性事務seata。service。disable-global-transaction= falseseata。registry。type=nacos#註冊服務的名稱seata。nacos。application=seata-serverseata。nacos。server-addr=127。0。0。1:8848#配置名稱空間,預設為publicseata。nacos。namespace=publicseata。nacos。group=SEATA_GROUPseata。nacos。username=nacosseata。nacos。password=nacosseata。config。nacos。server-addr=127。0。0。1:8848#配置名稱空間,預設為publicseata。config。nacos。namespace=publicseata。config。nacos。group=DEFAULT_GROUP#配置中心的賬號密碼seata。config。nacos。username=nacosseata。config。nacos。password=nacos

nacos-config。txt這個配置檔案在seata的版本中不存在請自行下載,或者參考上一篇的seata0。7。0的版本中有

vgroup-mapping。my_test_tx_group要與配置檔案/conf/nacos-config。txt的配置一致

SpringBoot整合分散式事務Seata

4.注意點,如果選擇的是1.4.0版本的seata

再1。4。0的版本中seata的namespace是為空的,如果配置檔案中寫為public,那麼registry。conf也要寫為public,不然會註冊失敗namespace=“”

SpringBoot整合分散式事務Seata

5.SpringBoot開啟分散式事務seata需要注意

需要使用DataSourceProxy代理資料來源使分散式事務生效,以下為自定義配置多資料來源,可以自行簡單配置,不然使用seata的註解

@GlobalTransactional不生效

@Data@Configuration@ConfigurationProperties(prefix = “spring。datasource。druid”)@MapperScan(basePackages = {“com。south。wires。mapper”}, sqlSessionTemplateRef = “dbSqlSessionTemplate”)public class DataSourcesConfig { private String filters; private String url; private String username; private String password; private String driverClassName; private int initialSize; private int minIdle; private int maxActive; private long maxWait; private long timeBetweenEvictionRunsMillis; private long minEvictableIdleTimeMillis; private String validationQuery; private boolean testWhileIdle; private boolean testOnBorrow; private boolean testOnReturn; private boolean poolPreparedStatements; private int maxPoolPreparedStatementPerConnectionSize; @Bean(name = “dbDataSource”) @Qualifier(“dbDataSource”) public DataSource mysqlDataSource() { return CreateDataSource。getDataSource(filters,url,username,password,driverClassName,initialSize, minIdle,maxActive,maxWait,timeBetweenEvictionRunsMillis,minEvictableIdleTimeMillis,validationQuery,testWhileIdle, testOnBorrow,testOnReturn,poolPreparedStatements,maxPoolPreparedStatementPerConnectionSize); } @Primary @Bean public DataSourceProxy dataSource(DataSource dbDataSource) { return new DataSourceProxy(dbDataSource); } @Bean(name = “dbSqlSessionFactory”) public SqlSessionFactory mysqlSqlSessionFactory(DataSource dataSource) throws Exception { System。out。println(dataSource); MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean(); bean。setDataSource(dataSource); //修復TypeAliases配置失敗的問題 bean。setVfs(SpringBootVFS。class); //對應mybatis。type-aliases-package配置 bean。setTypeAliasesPackage(“com。south。wires。entity”); bean。setMapperLocations(new PathMatchingResourcePatternResolver()。getResources(“classpath:mapper/*Mapper。xml”)); //開啟駝峰對映 bean。getObject()。getConfiguration()。setMapUnderscoreToCamelCase(true); //分頁外掛 Interceptor interceptor = new PaginationInterceptor(); Properties properties = new Properties(); //資料庫 properties。setProperty(“helperDialect”, “mysql”); //是否分頁合理化 properties。setProperty(“reasonable”, “false”); interceptor。setProperties(properties); bean。setPlugins(new Interceptor[] {interceptor}); return bean。getObject(); } @Bean(name = “dbTransactionManager”) public DataSourceTransactionManager mysqlTransactionManager(@Qualifier(“dbDataSource”) DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = “dbSqlSessionTemplate”) public SqlSessionTemplate mysqlSqlSessionTemplate(@Qualifier(“dbSqlSessionFactory”) SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); }}

SpringBoot整合分散式事務Seata

2。如果單純配置了DataSourceProxy,報錯

io。seata。common。exception。ShouldNeverHappenException: Can‘t find any object of class org。springframework。context。ApplicationContext

SpringBoot整合分散式事務Seata

3。新增以下配置可以解決io。seata。common。exception。ShouldNeverHappenException報錯

import io。seata。spring。annotation。GlobalTransactionScanner;import org。springframework。context。annotation。Bean;import org。springframework。context。annotation。Configuration;import org。springframework。context。annotation。DependsOn;import static io。seata。common。Constants。BEAN_NAME_FAILURE_HANDLER;import static io。seata。common。Constants。BEAN_NAME_SPRING_APPLICATION_CONTEXT_PROVIDER;@Configurationpublic class SeataAutoConfig { @Bean @DependsOn({BEAN_NAME_SPRING_APPLICATION_CONTEXT_PROVIDER, BEAN_NAME_FAILURE_HANDLER}) public GlobalTransactionScanner globalTransactionScanner(){ //test1 是 applicationid,my_test_tx_group 是 txServiceGroup return new GlobalTransactionScanner(“test1”,“my_test_tx_group”); }}

SpringBoot整合分散式事務Seata

6、控制層整合

1。需要添加註解@GlobalTransactional,將RootContext。getXID()向下一個服務進行傳遞

第一個服務

@ResponseBody @RequestMapping(“t1”) @GlobalTransactional public void test() throws TransactionException { String xid= RootContext。getXID(); //簡單的例子 OrderData order=new OrderData(); order。setOrderId(IdUtil。simpleUUID()); order。setUserId(1); //儲存資料 orderDataService。save(order); Map map=new HashMap<>(); map。put(“num”,5); map。put(“orderId”,order。getOrderId()); map。put(“XID”,xid); //請求另外一個服務,進行資料的更新, JSONObject jsonObject= JSONObject。parseObject(HttpUtil。createGet(“http://localhost:8051/test/t2”)。form(map)。execute()。body()); //t2介面被設定返回異常狀態碼,所以捕獲異常狀態碼手動回滾 if(!jsonObject。getString(“code”)。equals(“0”)){ GlobalTransactionContext。reload(xid)。rollback(); } }

SpringBoot整合分散式事務Seata

第二個服務RootContext。bind(XID);

SpringBoot整合分散式事務Seata

2。斷點除錯查詢seata庫,可以檢視到往資料庫中添加了資料

SpringBoot整合分散式事務Seata

branch_table

SpringBoot整合分散式事務Seata

global_table

SpringBoot整合分散式事務Seata

lock_table

SpringBoot整合分散式事務Seata

業務庫新增表undo_log,不然會報錯

相關文章

頂部