Bank transferFor example, if bank A transfers 500 yuan to bank B, the process must be bank A-500, bank B+500, in this process
Either we all succeed or we all die. First of all, the numbers of bank A and bank B must be in different databases. If in the transfer process, bank A first deposits the money -500, and then there is A problem when bank B+500, if the transaction is not rolled back, then there will be A problem of 500 yuan lost, that is, there is A problem
Transaction consistencyThe problem.
A, JTA
Atomikos is an open source class transaction manager that provides value-added services for the Java platform.
How it works: Distributed transactions include a transaction manager and an XA-enabled resource manager. The resource manager is our DB, and the transaction manager is responsible for regulating and controlling all transactions designed to participate in the DB.
Personal understanding: After Atomikos obtains the connection to the database, it will shield the transaction control at the bottom of the database, and then hand it over to Atomikos for unified scheduling and control.
<! <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency>Copy the code
3. Configuration classes
@Configuration
@MapperScan(basePackages = "com.example.mapper.db1", sqlSessionFactoryRef = "db1SqlSessionFactory")
public class DB1DataSourcesConfig {
@Primary
@Bean(name = "db1DataSource"Public DataSource DataSource (DB1Config DB1Config) {MysqlXADataSource = new MysqlXADataSource(); mysqlXADataSource.setUrl(DB1Config.getUrl_jdbc()); mysqlXADataSource.setUser(DB1Config.getUsername()); mysqlXADataSource.setPassword(DB1Config.getPassword()); mysqlXADataSource.setPinGlobalTxToPhysicalConnection(true); AtomikosDataSourceBean = new AtomikosDataSourceBean(); atomikosDataSourceBean.setXaDataSource(mysqlXADataSource); atomikosDataSourceBean.setUniqueResourceName("db1DataSource");
return atomikosDataSourceBean;
}
@Primary
@Bean(name = "db1SqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:/mapper/db1/*.xml"));
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
configuration.setMapUnderscoreToCamelCase(true);
sessionFactoryBean.setConfiguration(configuration);
return sessionFactoryBean.getObject();
}
@Primary
@Bean(name = "db1SqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
returnnew SqlSessionTemplate(sqlSessionFactory); }}Copy the code
So that’s basically the configuration, so I just wrote the configuration of one database, and the other one is just like this one, where the database information has changed.
There is no data before modification
Let’s see if the user information can be rolled back if there is an exception when modifying the score.
The results of
First, the code reported an error at line 39. If we follow our logic, if we failed to modify the score, then the age of the corresponding user was also unsuccessful, but the result shows that the age of the user was changed anyway, obviously the interface is not managed by distributed transactions.
The transaction withLet’s see if that doesn’t happen. (
Methods add
@Transactional
Annotations can be)
It ensures the consistency of transactions and the security and accuracy of data.
https://github.com/liangbintao/distributed_transaction.git
For more information, please follow the wechat official account: The growth of a programmer