import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
/**
- @Author 一一哥Sun
- @Date Created in 2020/4/3
- @Description Description
*/
@Repository
public interface UserRepository extends JpaRepository<User, Long>,JpaSpecificationExecutor {
}
#### **6. 配置数据源及事务管理器等**
这里的配置是最关键的,一般代码出问题都是因为这里有问题。
>
> *这里针对两个数据库,分别设置两个数据源goodsDataSource与userDataSource。这里的DataSource必须是XADataSource类型的数据源才行,并且利用AtomikosDataSourceBean讲数据源配置进去。*
>
>
> *还有分别设置实体类管理工厂goodsEntityManagerFactory与userEntityManagerFactory。*
>
>
> *再分别设置事务管理器goodsTransactionManager与userTransactionManager。*
>
>
> *还要创建一个用来整合多个事务管理器的JtaTransactionManager,负责回滚到多个数据源中。*
>
>
> *但要注意区分是否是Primary配置。*
>
**db1数据源配置类GoodsDataSourceConfig**
package com.yyg.boot.config;
import com.alibaba.druid.pool.xa.DruidXADataSource;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Objects;
/**
-
@Author 一一哥Sun
-
@Date Created in 2020/4/18
-
@Description 商品数据源配置类
*/
@Configuration
@EnableJpaRepositories(basePackages = {“com.yyg.boot.dao.db01”}, entityManagerFactoryRef = “goodsEntityManagerFactory”, transactionManagerRef = “goodsTransactionManager”)
public class GoodsDataSourceConfig {@Resource
private JpaProperties jpaProperties;/**
-
第一个数据源
*/
@Primary
@Bean(name = “goodsDataSource”)
public DataSource goodsDataSource() {
DruidXADataSource druidXADataSource = new DruidXADataSource();
druidXADataSource.setUrl(“jdbc:mysql://localhost:3306/db1?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC”);
druidXADataSource.setUsername(“root”);
druidXADataSource.setPassword(“syc”);
druidXADataSource.setDefaultAutoCommit(false);
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
atomikosDataSourceBean.setXaDataSource(druidXADataSource);
atomikosDataSourceBean.setUniqueResourceName(“goodsDataSource”);
atomikosDataSourceBean.setPoolSize(5);return atomikosDataSourceBean;
}
/**
- 商品实体类管理工厂
*/
@Primary
@Bean(name = “goodsEntityManagerFactory”)
public LocalContainerEntityManagerFactoryBean goodsEntityManagerFactory(EntityManagerFactoryBuilder builder) {
return builder.dataSource(goodsDataSource())
.properties(jpaProperties.getProperties())
//设置实体类所在位置:类或包
.packages(“com.yyg.boot.entity.db1”)
//持久化单元名称
.persistenceUnit(“goodsPersistenceUnit”)
.build();
}
/**
- 商品事务管理器
*/
@Primary
@Bean(name = “goodsTransactionManager”)
public PlatformTransactionManager goodsTransactionManager(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(Objects.requireNonNull(goodsEntityManagerFactory(builder).getObject()));
}
-
}
**db4数据源配置类GoodsDataSourceConfig**
package com.yyg.boot.config;
import com.alibaba.druid.pool.xa.DruidXADataSource;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Objects;
/**
-
@Author 一一哥Sun
-
@Date Created in 2020/4/18
-
@Description 商品数据源配置类
*/
@Configuration
@EnableJpaRepositories(basePackages = {“com.yyg.boot.dao.db02”},entityManagerFactoryRef = “userEntityManagerFactory”,transactionManagerRef = “userTransactionManager”)
public class UserDataSourceConfig {/**
- 自动注入jpa配置
*/
@Resource
private JpaProperties jpaProperties;
@Bean(name = “userDataSource”)
public DataSource db4DataSource() {
DruidXADataSource druidXADataSource = new DruidXADataSource();
druidXADataSource.setUrl(“jdbc:mysql://localhost:3306/db4?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC”);
druidXADataSource.setUsername(“root”);
druidXADataSource.setPassword(“syc”);
druidXADataSource.setDefaultAutoCommit(false);AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean(); atomikosDataSourceBean.setXaDataSource(druidXADataSource); atomikosDataSourceBean.setUniqueResourceName("userDataSource"); atomikosDataSourceBean.setPoolSize(5); return atomikosDataSourceBean;
}
/**
- 将数据源、连接池、以及其他配置策略进行封装返回给事务管理器
- 自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
*/
@Bean(name = “userEntityManagerFactory”)
public LocalContainerEntityManagerFactoryBean userEntityManagerFactory(EntityManagerFactoryBuilder builder){
return builder.dataSource(db4DataSource())
.properties(jpaProperties.getProperties())
//设置实体类所在位置:类或包
.packages(“com.yyg.boot.entity.db2”)
//持久化单元名称
.persistenceUnit(“userPersistenceUnit”)
.build();
}
/**
- 返回数据源的事务管理器
*/
@Bean(name = “userTransactionManager”)
public PlatformTransactionManager userTransactionManager(EntityManagerFactoryBuilder builder){
return new JpaTransactionManager(Objects.requireNonNull(userEntityManagerFactory(builder).getObject()));
}
- 自动注入jpa配置
}
**创建用来整合多数据源的事务管理器JtaTransactionManager**
package com.yyg.boot.config;
import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.jta.JtaTransactionManager;
import javax.transaction.UserTransaction;
/**
-
@Author 一一哥Sun
-
@Date Created in 2020/4/19
-
@Description Description
*/
@Configuration
public class JtaTransactionManagerConfig {@Primary
@Bean(name = “jtaTransactionManager”)
public JtaTransactionManager regTransactionManager () {
UserTransactionManager userTransactionManager = new UserTransactionManager();
UserTransaction userTransaction = new UserTransactionImp();
return new JtaTransactionManager(userTransaction, userTransactionManager);
}
}
#### **7. 创建Service及其实现类**
>
> *注意:*
>
>
> *此处一定要通过@Transactional注解来明确指明所用的事务管理器,否则当多数据源时可能只能执行一个数据里的增删改操作,且此处应该设置Spring的事务传播属性为propagation =Propagation.NEVER,不使用单个数据源自己的事务,统一交由jtaTransactionManager的事务来管理。*
>
**定义GoodsService接口**
package com.yyg.boot.service;
import com.yyg.boot.entity.db1.Goods;
import java.util.List;
/**
-
@Author 一一哥Sun
-
@Date Created in 2020/4/7
-
@Description Description
*/
public interface GoodsService {List findAll();
Goods addGoods(Goods goods);
}
**GoodsServiceImpl实现**
package com.yyg.boot.service.impl;
import com.yyg.boot.dao.db01.GoodsRepository;
import com.yyg.boot.entity.db1.Goods;
import com.yyg.boot.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.List;
/**
-
@Author 一一哥Sun
-
@Date Created in 2020/4/7
-
@Description Description
-
注意:此处一定要通过@Transactional注解来明确指明所用的事务管理器,否则当多数据源时可能只能执行一个数据里的增删改操作.
-
且此处应该设置Spring的事务传播属性为propagation =Propagation.NEVER,不使用单个数据源自己的事务,统一交由jtaTransactionManager的事务来管理.
*/
@Service
@Transactional(transactionManager = “goodsTransactionManager”,rollbackFor = Exception.class,propagation =Propagation.NEVER)
public class GoodsServiceImpl implements GoodsService {@Autowired
private GoodsRepository goodsRepository;@Override
public List findAll() {
return goodsRepository.findAll();
}@Override
public Goods addGoods(Goods goods) {
try {
return goodsRepository.save(goods);
}catch (Exception e){
//强制手动事务回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return null;
}
}
**定义UserService接口**
package com.yyg.boot.service;
import com.yyg.boot.entity.db2.User;
import java.util.List;
/**
-
@Author 一一哥Sun
-
@Date Created in 2020/4/7
-
@Description Description
*/
public interface UserService {List findAll();
User addUser(User user);
}
**UserServiceImpl实现**
package com.yyg.boot.service.impl;
import com.yyg.boot.dao.db02.UserRepository;
import com.yyg.boot.entity.db2.User;
import com.yyg.boot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.List;
/**
-
@Author 一一哥Sun
-
@Date Created in 2020/4/7
-
@Description Description
-
注意:此处一定要通过@Transactional注解来明确指明所用的事务管理器,否则当多数据源时可能只能执行一个数据里的增删改操作.
-
且此处应该设置Spring的事务传播属性为propagation =Propagation.NEVER,不使用单个数据源自己的事务,统一交由jtaTransactionManager的事务来管理.
*/
@Service
@Transactional(transactionManager = “userTransactionManager”,rollbackFor = Exception.class,propagation =Propagation.NEVER)
public class UserServiceImpl implements UserService {@Autowired
private UserRepository userRepository;@Override
public List findAll() {
return userRepository.findAll();
}@Override
public User addUser(User user) {
try {
return userRepository.save(user);
}catch (Exception e){
//强制手动事务回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return null;
}
}
#### **8. 创建Controller进行测试**
package com.yyg.boot.web;
import com.yyg.boot.entity.db1.Goods;
import com.yyg.boot.entity.db2.User;
import com.yyg.boot.service.GoodsService;
import com.yyg.boot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
/**
-
@Author 一一哥Sun
-
@Date Created in 2020/4/3
-
@Description Description
*/
@RestController
public class TransactionController {@Autowired
private UserService userService;@Autowired
private GoodsService goodsService;@Transactional(value = “jtaTransactionManager”, rollbackFor = Exception.class)
@GetMapping(“/add”)
public ResponseEntity addTest() {
Goods goods = new Goods();
goods.setId(44L);
goods.setName(“iPhone se”);
goodsService.addGoods(goods);User user = new User(); user.setSex("男"); user.setUsername("一一哥"); user.setAddress("上海"); user.setBirthday(new Date()); userService.addUser(user); return ResponseEntity.ok("添加成功");
}
//在该接口中故意制造一个除零异常
@Transactional(value = “jtaTransactionManager”, rollbackFor = Exception.class)
@GetMapping(“/add2”)
public ResponseEntity addTest2() {
Goods goods = new Goods();
goods.setId(44L);
goods.setName(“iPhone se”);
goodsService.addGoods(goods);
给大家的福利
零基础入门
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
同时每个成长路线对应的板块都有配套的视频提供:
因篇幅有限,仅展示部分资料
网络安全面试题
绿盟护网行动
还有大家最喜欢的黑客技术
网络安全源码合集+工具包
所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~
加入社区》https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0