Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the dynamic data source framework that supports snooping SQL, sensing transaction state, and backtracking data sources?

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly explains "what is the dynamic data source framework that supports monitoring SQL, perceiving transaction status, and backtracking data sources". The content of the explanation in this article is simple and clear, and it is easy to learn and understand. please follow the editor's train of thought to study and learn what is the dynamic data source framework that supports monitoring SQL, perceiving transaction status, and backtracking data sources.

Rename the project

After easymulti-datasource-spring-boot-starter, the author developed hotkit-r2dbc, both of which support dynamic data source switching. The former supports mybatis framework and the latter supports responsive programming spring-data-r2dbc framework. Since they are both ORM frameworks, it is better to merge them into one project for maintenance.

The original easymulti-datasource-spring-boot-starter project on GitHub has been renamed easymulti-datasource, while the original easymulti-datasource-spring-boot-starter module has been renamed easymulti-datasource-mybatis, with the version number starting from 3.0.1. The new version adds easymulti-datasource-r2dbc (that is, the original hotkit-r2dbc).

Project background

Dynamic switching of multiple data sources seems to have become the standard configuration of micro-services. After doing so many projects, I found that each project needs to be equipped with a dynamic data source, and each project needs to write an aspect to achieve dynamic switching. Therefore, I encapsulated these tedious configurations as starter and used them immediately.

There are two modules in easymulti-datasource:

Easymulti-datasource-mybatis (formerly easymulti-datasource-spring-boot-starter)

Easymulti-datasource-r2dbc (formerly hotkit-r2dbc)

Easymulti-datasource-mybatis

Mybatis version of the multi-data source framework, providing declarative and programmatic dynamic switching of data sources.

Easymulti-datasource-mybatis automatically integrates mybatis-plus and provides two dynamic multi-data source modes, namely master-slave data source mode and non-master-slave multi-data source mode. Each data source uses independent connection pool configuration, and connection pool can be configured separately for each data source.

Supporting dynamic switching of multiple data sources is not the biggest highlight of the easymulti-datasource-mybatis framework. The main features that distinguish easymulti-datasource-mybatis from other dynamic data source switching frameworks are as follows:

Support listening to SQL and listening to sql that modifies some fields of a table, which is used to implement buried point events

Support for transaction status monitoring and registration of transaction listeners to complete some background operations during transaction rollback / commit

For more information, please see wiki.

Dependent configuration

In maven, use:

Com.github.wujiuye easymulti-datasource-mybatis ${version}

The old version is:

Com.github.wujiuye easymulti-datasource-spring-boot-starter ${version}

The description of version selection considerations is shown in the following figure.

Dynamically switch data sources

Use annotations to switch data sources: @ EasyMutiDataSource

Use API to switch the data source: DataSourceContextHolder#setDataSource.

Register transaction listeners in AOP

Turn on the switch to trace the transaction method invocation link in the application configuration file, configured as follows.

# # Link easymuti: transaction: open-chain: true called by monitoring transaction method

Define the aspect, intercept the Mapper method, and implement the logic to update the cache in the surround method, as follows.

TransactionInvokeContext.currentExistTransaction: determines whether there is a transaction on the current calling link

TransactionInvokeContext.addCurrentTransactionMethodPopListener: binds a PopTransactionListener to the current transaction, which is called when the transaction is committed or rolled back.

As shown in the above code, the first step is to determine whether there is a transaction on the current calling link. If so, a listener is injected into the current transaction, and the listener completes the cache update logic. If there is no transaction, the update cache logic is executed when the target method is executed and no exception is thrown.

Monitor SQL

Easymulti-datasource-mybatis supports sql buried point listening and monitoring transaction status. If the current sql execution exists in a transaction, the sql listener will not be called back until the transaction is committed.

Step 1: enable sql burial listening and transaction call link tracing.

Easymuti: transaction: open-chain: true sql-watcher: enable: true

Step 2: write observers, there can be more than n, and multiple observers can observe the same table, or even the same field.

@ Component @ Slf4j public class TestTableFieldObserver implements TableFieldObserver InitializingBean {@ Override public Set observeMetadatas () {/ / register here which fields of which tables to listen} / * when listening to sql, it is called synchronously * * @ param commandType event type * @ param matchResult matching ITEM * @ return returns asynchronous consumer * / @ Override public AsyncConsumer observe (CommandType commandType MatchItem matchResult) {/ / synchronous consumption / / this is before sql execution You can do something before sql execution, such as comparing old and new data, where old data / asynchronous consumption is found, when sql execution is complete, or when transaction method execution is complete (if there is a transaction) Completion refers to: normal execution completes or method exception exit return throwable-> {/ / sql execution throws an exception without handling if (throwable! = null) {return } / / consumption event / /. };}}

The observe method is called synchronously when listening for sql, and the AsyncConsumer returned by this method is called back after the transaction is committed, and will not be called if the transaction is rolled back.

If more than one transaction occurs on the calling link, all AsyncConsumer registered on the transaction will be called back only when the transaction of the current method is committed, depending on the propagation mechanism of the transaction.

Easymulti-datasource-r2dbc

Spring-data-r2dbc version of multiple data source components for responsive programming.

Easymulti-datasource-r2dbc implements a dynamic routing interface for spring-data-r2dbc and provides support for declarative and programmatic multi-source dynamic switching for reactive programming. It also supports two multi-data source modes, covering common multi-data source usage scenarios, namely master-slave mode and Cluster mode. Cluster mode supports the configuration of up to 3 data sources, while master-slave mode supports one master and one slave.

Add dependencies and configure data sources

After using easymulti-datasource-r2dbc, you no longer need to add spring-boot-starter-data-r2dbc dependencies to your project, nor do you need to add spring-data-r2dbc dependencies.

The easymulti-datasource-r2dbc version number corresponds to the spring-data-r2dbc version number:

Easymulti-datasource-r2dbcspring-data-r2dbc3.0.1-RELEASE1.1.0.RELEASE

Add easymulti-datasource-r2dbc dependencies to the project as follows.

Com.github.wujiuye easymulti-datasource-r2dbc ${version}

At this point, you only need to add additional driver dependencies for the database type used, for example, to add the r2dbc driver for mysql.

Dev.miku r2dbc-mysql 0.8.2.RELEASE

If master-slave mode is used, the following configuration is used.

Easymuti: database: r2dbc: master-slave-mode: master: url: r2dbc:mysql://127.0.0.1:3306/r2dbc_stu username: root password: pool: max-size: 5 idel-timeout: 60 slave: url: r2dbc:mysql://127.0.0.1 : 3306/r2dbc_stu username: root password: pool: max-size: 5 idel-timeout: 60

Master will be set to the default data source, slave will be configured, none can be empty. Although slave is allowed to be empty, it is not necessary to use easymulti-datasource-r2dbc if you really do not need multiple data sources.

If Cluster mode is used, the following configuration is used.

Easymuti: database: r2dbc: cluster-mode: first: url: r2dbc:mysql://127.0.0.1:3306/r2dbc_stu username: root password: pool: max-size: 5 idel-timeout: 60 second: url: r2dbc:mysql://127.0.0.1:3306 / r2dbc_stu username: root password: pool: max-size: 5 idel-timeout: 60 third: url: r2dbc:mysql://127.0.0.1:3306/r2dbc_stu username: root password: pool: max-size: 5 idel-timeout: 60

Where first will be set to the default data source, second and third can be empty.

Declarative dynamic switching of data sources

Declaratively dynamically switching data sources means using annotations to dynamically switch data sources. You only need to add @ R2dbcDataBase annotations to the public method or class of spring bean, and specify the value attribute of the annotations as the data source used.

The sample code is as follows.

@ Service public class PersonService {@ Resource private PersonRepository personRepository; / / the return type of the method is Mono test @ R2dbcDataBase (MasterSlaveMode.Master) @ Transactional (rollbackFor = Throwable.class) public Mono addPerson (Person...) Persons) {Mono txOp = null; for (Person person: persons) {if (txOp = = null) {txOp = personRepository.insertPerson (person.getId (), person.getName (), person.getAge ());} else {txOp = txOp.then (personRepository.insertPerson (person.getId (), person.getName (), person.getAge () }} return txOp;} / / method return value type is Flux test @ R2dbcDataBase (MasterSlaveMode.Master) @ Transactional (rollbackFor = Throwable.class) public Flux addPersons (Flux persons) {return persons.flatMap (person-> personRepository.insertPerson (person.getId (), person.getName (), person.getAge ();}}

For master-slave mode, the optional value of the value attribute of the @ R2dbcDataBase annotation can be found in the constant declared by the MasterSlaveMode interface.

For Cluster mode, the optional value of the value attribute of the @ R2dbcDataBase annotation can be found in the constant declared by the ClusterMode interface.

Programmers dynamically switch data sources

The implementation of declarative switching data sources relies on programmatic switching data sources, so we can also write code to switch data sources directly without changing the method to public exposure.

You only need to call the static method putDataSource provided by EasyMutiR2dbcRoutingConnectionFactory to write to the data source used by Context, as follows.

Public class RoutingTest extends SupporSpringBootTest {@ Resource private DatabaseClient client; @ Resource private ReactiveTransactionManager reactiveTransactionManager; @ Test public void test () throws InterruptedException {TransactionalOperator operator = TransactionalOperator.create (reactiveTransactionManager) Mono atomicOperation = client.execute ("INSERT INTO person (id, name, age) VALUES (: id,: name,: age)") .bind ("id", "joe") .bind ("name", "Joe") .bind ("age") 34) .fetch () .rowsUpdated () .then (client.execute ("INSERT INTO person (id, name) VALUES (: id,: name)") .bind ("id", "joe") .bind ("name") "Joe") .fetch () .rowsUpdated () .then () / / wrapper transaction Mono txOperation = operator.transactional (atomicOperation); / / wrapper switch data source EasyMutiR2dbcRoutingConnectionFactory.putDataSource (txOperation, MasterSlaveMode.Slave). Subscribe (); TimeUnit.SECONDS.sleep (Integer.MAX_VALUE);}}

It is important to note that if you need to use transactions, you must first call the transactional method of the TransactionalOperator object, and then call the putDataSource method of EasyMutiR2dbcRoutingConnectionFactory.

Thank you for your reading. the above is the content of "what is the dynamic data source framework that supports monitoring SQL, perceiving transaction status and backtracking data sources". After the study of this article, I believe you have a deeper understanding of what is the dynamic data source framework that supports monitoring SQL, perceiving transaction status and backtracking data sources, and the specific usage needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report