一、上一篇seata的整合
上一篇seata的版本是0。7。0,因為與匯入的依賴io。seata版本不同導致整合失敗,所以換為seata1。4。0版本號
關於seata的整合注意配置,注意選擇的driverClassName以及store。mode修改為db
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的相關依賴
三、啟動seata
1.如果版本不是1.4.0會報錯,即依賴與seata下載的服務版本不一致
Exception in thread
“main”
io。seata。common。exception。FrameworkException: No available service
2.選擇一致的版本
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的配置一致
4.注意點,如果選擇的是1.4.0版本的seata
再1。4。0的版本中seata的namespace是為空的,如果配置檔案中寫為public,那麼registry。conf也要寫為public,不然會註冊失敗namespace=“”
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); }}
2。如果單純配置了DataSourceProxy,報錯
io。seata。common。exception。ShouldNeverHappenException: Can‘t find any object of class org。springframework。context。ApplicationContext
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”); }}
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
第二個服務RootContext。bind(XID);
2。斷點除錯查詢seata庫,可以檢視到往資料庫中添加了資料
branch_table
global_table
lock_table
業務庫新增表undo_log,不然會報錯