Springboot management of multiple data source transactions and rollback _springboot

Source: Internet
Author: User
Tags rollback

Multiple data sources are used in recently developed projects, and two rollback events with different transactions are used to ensure data consistency. Some of the code altogether refer to: MySQL as a case.

Configuration file


Spring.datasource.prod.driver-class-name=com.mysql.jdbc.driver
Spring.datasource.prod.url=jdbc:mysql://127.0.0.1:3306/test
Spring.datasource.prod.username=root
Spring.datasource.prod.password=root




Spring.datasource.dev.driver-class-name=com.mysql.jdbc.driver
Spring.datasource.dev.url=jdbc:mysql://127.0.0.1:3306/test1
Spring.datasource.dev.username=root
Spring.datasource.dev.password=root


Configure data sources and the management of transactions
Package com.lanwon.config;


Import java.sql.SQLException;


Import Javax.annotation.Resource;
Import Javax.sql.DataSource;
Import Org.apache.ibatis.session.SqlSessionFactory;
Import Org.mybatis.spring.SqlSessionFactoryBean;
Import Org.mybatis.spring.annotation.MapperScan;
Import Org.springframework.beans.factory.annotation.Qualifier;
Import Org.springframework.beans.factory.annotation.Value;
Import Org.springframework.context.annotation.Bean;
Import org.springframework.context.annotation.Configuration;
Import Org.springframework.context.annotation.Primary;
Import Org.springframework.core.io.support.PathMatchingResourcePatternResolver;
Import Org.springframework.core.io.support.ResourcePatternResolver;
Import Org.springframework.jdbc.datasource.DataSourceTransactionManager;
Import Com.alibaba.druid.pool.DruidDataSource;


/**
* @author DZB
* @date August 23, 2017
* Data Source Dev
*/
@Configuration # Different data sources should be layered when scanning DAO, otherwise you can only be bound once.
@MapperScan (basepackages= "Com.lanwon.mapper.dev", sqlsessionfactoryref= "Devsqlsessionfactory")
public class Devdatasourceconfig {


@Value ("${spring.datasource.dev.driver-class-name}")
Private String Dbdriver;


@Value ("${spring.datasource.dev.url}")
Private String Dburl;


@Value ("${spring.datasource.dev.username}")
Private String UserName;


@Value ("${spring.datasource.dev.password}")
private String password;


@Resource
Private Globaldbconfig Globaldbconfig;


private static final String Mapper_path = "Classpath*:/mapper/dev/*.xml";


private static final String entity_package = "Com.lanwon.entity.dev";


@Bean (name = "Devdatasource")
@Primary
Public DataSource Devdatasource () throws SQLException {
Druiddatasource DataSource = new Druiddatasource ();
Datasource.setdriverclassname (Dbdriver);
Datasource.seturl (Dburl);
Datasource.setusername (UserName);
Datasource.setpassword (password);
Datasource.setfilters (Globaldbconfig.getdbfilters ());
Datasource.setmaxactive (Globaldbconfig.getdbmaxactive ());
Datasource.setmaxwait (Globaldbconfig.getdbmaxwait ());
Datasource.setminidle (Globaldbconfig.getdbminidle ());
Datasource.settimebetweenevictionrunsmillis (globaldbconfig
. Getdbtimebetweenevictionrunsmillis ());
Datasource.setminevictableidletimemillis (globaldbconfig
. Getdbminevictableidletimemillis ());
Datasource.settestwhileidle (Globaldbconfig.isdbtestwhileidle ());
Datasource.setvalidationquery (Globaldbconfig.getdbvalidationquery ());
Datasource.settestonborrow (Globaldbconfig.isdbtestonborrow ());
Datasource.settestonreturn (Globaldbconfig.isdbtestonreturn ());
Datasource.setpoolpreparedstatements (globaldbconfig
. isdbpoolpreparedstatements ());
Datasource.setmaxopenpreparedstatements (globaldbconfig
. getdbmaxopenpreparedstatements ());
Datasource.init ();
return dataSource;
}



@Bean (name = "Devtransactionmanager")
@Primary
Public Datasourcetransactionmanager Devtransactionmanager ()
Throws SQLException {
return new Datasourcetransactionmanager (Devdatasource ());
}


@Bean (name = "Devsqlsessionfactory")
@Primary//default
Public Sqlsessionfactory Devsqlsessionfactory (
@Qualifier ("Devdatasource") DataSource Ddatasource)
Throws Exception {
Final Sqlsessionfactorybean sessionfactory = new Sqlsessionfactorybean ();
Sessionfactory.setdatasource (Ddatasource);
Resourcepatternresolver resolver = new Pathmatchingresourcepatternresolver ();
Sessionfactory.setmapperlocations (Resolver.getresources (Mapper_path));
Sessionfactory.settypealiasespackage (Entity_package);
return Sessionfactory.getobject ();
}


}




Import java.sql.SQLException;
Import Javax.annotation.Resource;
Import Javax.sql.DataSource;
Import Org.apache.ibatis.session.SqlSessionFactory;
Import Org.mybatis.spring.SqlSessionFactoryBean;
Import Org.mybatis.spring.annotation.MapperScan;
Import Org.springframework.beans.factory.annotation.Qualifier;
Import Org.springframework.beans.factory.annotation.Value;
Import Org.springframework.context.annotation.Bean;
Import org.springframework.context.annotation.Configuration;
Import Org.springframework.context.annotation.Primary;
Import Org.springframework.core.io.support.PathMatchingResourcePatternResolver;
Import Org.springframework.core.io.support.ResourcePatternResolver;
Import Org.springframework.jdbc.datasource.DataSourceTransactionManager;
Import Com.alibaba.druid.pool.DruidDataSource;


/**
* @author DZB
* @date August 23, 2017
* Data Source Prod
*/
@Configuration
@MapperScan (basepackages= "Com.lanwon.mapper.prod", sqlsessionfactoryref= "Prodsqlsessionfactory")
public class Proddatasourcesconfig {


@Value ("${spring.datasource.prod.driver-class-name}")
Private String Dbdriver;


@Value ("${spring.datasource.prod.url}")
Private String Dburl;


@Value ("${spring.datasource.prod.username}")
Private String UserName;


@Value ("${spring.datasource.prod.password}")
private String password;


@Resource
Private Globaldbconfig Globaldbconfig;


private static final String Mapper_path = "Classpath*:/mapper/prod/*.xml";


private static final String entity_package = "Com.lanwon.entity.prod";


@Bean (name = "Proddatasource")
Public DataSource Proddatasource () throws SQLException {
Druiddatasource DataSource = new Druiddatasource ();
Datasource.setdriverclassname (Dbdriver);
Datasource.seturl (Dburl);
Datasource.setusername (UserName);
Datasource.setpassword (password);
Datasource.setfilters (Globaldbconfig.getdbfilters ());
Datasource.setmaxactive (Globaldbconfig.getdbmaxactive ());
Datasource.setmaxwait (Globaldbconfig.getdbmaxwait ());
Datasource.setminidle (Globaldbconfig.getdbminidle ());
Datasource.settimebetweenevictionrunsmillis (globaldbconfig
. Getdbtimebetweenevictionrunsmillis ());
Datasource.setminevictableidletimemillis (globaldbconfig
. Getdbminevictableidletimemillis ());
Datasource.settestwhileidle (Globaldbconfig.isdbtestwhileidle ());
Datasource.setvalidationquery (Globaldbconfig.getdbvalidationquery ());
Datasource.settestonborrow (Globaldbconfig.isdbtestonborrow ());
Datasource.settestonreturn (Globaldbconfig.isdbtestonreturn ());
Datasource.setpoolpreparedstatements (globaldbconfig
. isdbpoolpreparedstatements ());
Datasource.setmaxopenpreparedstatements (globaldbconfig
. getdbmaxopenpreparedstatements ());
Datasource.init ();
return dataSource;
}


@Bean (name = "Prodtransactionmanager")
Public Datasourcetransactionmanager Prodtransactionmanager ()
Throws SQLException {
return new Datasourcetransactionmanager (Proddatasource ());
}


@Bean (name = "Prodsqlsessionfactory")
Public Sqlsessionfactory Prodsqlsessionfactory (
@Qualifier ("Proddatasource") DataSource Pdatasource)
Throws Exception {
Final Sqlsessionfactorybean sessionfactory = new Sqlsessionfactorybean ();
Sessionfactory.setdatasource (Pdatasource);
Resourcepatternresolver resolver = new Pathmatchingresourcepatternresolver ();
Sessionfactory.setmapperlocations (Resolver.getresources (Mapper_path));
Sessionfactory.settypealiasespackage (Entity_package);
return Sessionfactory.getobject ();
}


}


Using the transaction manager

You only need to add a note @transactional in a method that requires a transaction and specify its value. Similarly, value values match the corresponding transaction management method name.


/**
* @author DZB
* @since 2016/7/5-22:21
*/
@Service
public class Userdetailserviceimpl implements Userdetailservice {


@Autowired
Private Userdetailmapper Userdetailmapper;


Public list<userdetail> Selectuserdetail () {
return Userdetailmapper.selectall ();
}




@Transactional (value= "Devtransactionmanager")
@Override
public int update (Userdetail userdetail) {
int b=userdetailmapper.update (userdetail);
return b;
}
}



@Service
public class Userinfoserviceimpl implements Userinfoservice {




@Autowired
Private Userinfomapper Userinfomapper;

@Autowired
Private Userdetailserviceimpl Detailserviceimpl;

Public list<userinfo> Selectuserinfo () {
return Userinfomapper.selectall ();
}


@Transactional (value= "Prodtransactionmanager")
@Override
public int update (UserInfo UserInfo) {
int a =userinfomapper.update (userInfo);
return A;
}


@Transactional (value= "Prodtransactionmanager")
@Override
public int update (String name1,string name2) {
int c=0;
UserInfo info = new UserInfo ();
Info.setid ("1");
Info.setusername (NAME1);
int b=userinfomapper.update (info);
if (b>0) {
Userdetail detail = new Userdetail ();
Detail.setid (1L);
Detail.setname (name2);
C=detailserviceimpl.update (detail);
}

return C;
}
}



Types of transactional propagation behavior

Spring provides 7 types of transactional propagation behavior in the Transactiondefinition interface.

They specify how transactions propagate when the transaction method and transaction method occur when nested calls are made:

Table 1 Transactional propagation behavior types

Transactional propagation behavior Type

Description

Propagation_required

If there is currently no transaction, create a new transaction, if there is already a transaction, join in the transaction. This is the most common choice.

Propagation_supports

Supports the current transaction, which is performed in a non transactional manner if there are currently no transactions.

Propagation_mandatory

Uses the current transaction and throws an exception if there are currently no transactions.

Propagation_requires_new

Creates a new transaction and suspends the current transaction if there is currently a transaction.

propagation_not_supported

Performs an operation in a non transactional manner, suspending the current transaction if there is currently a transaction.

Propagation_never

Executes in a non transactional manner and throws an exception if there is a current transaction.

propagation_nested

Executes within a nested transaction if there is currently a transaction. If there is currently no transaction, a similar operation is performed with Propagation_required.



Note: This article is my own experience of writing, if there is not very right place, please advise.
Project Source Github:https://github.com/sdmxdzb/transcations

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.