I. 배경
기본적인 이론적 지식의 많은 앞에 설명하고, 지금 우리가 전에 배우고 우리의 기초를 통합, 작은 밤의 몇 가지 간단한 포인트를 시작하십시오, 우리는 그것의 자신의 특히, 예를 나서야.
2. 그런 다음 우리가 계속 사건을 설명하는 작은의 첫 번째 조각을 가지고, 우리는 단지 그것을 설명하기 시작, 우리의 작은 사건을 잘 오늘, ADO를 설명하기 시작한다.
둘째, 프로젝트지도
1. 프로젝트 구조
셋째, 코드의 구성
1.pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.application.properties
#配置项目端口
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/threadtest?serverTimezone=GMT%2B8&characterEncoding=UTF-8
spring.datasource.primary.username=root
spring.datasource.primary.password=123456
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
3.ThreadPoolTaskExecutorConfig.java
@Configuration
public class ThreadPoolTaskExecutorConfig {
private static int CORE_POOL_SIZE = 5;
private static int MAX_POOL_SIZE = 1000;
@Bean(name="threadPoolTaskExecutor")
public ThreadPoolTaskExecutor serviceJobTaskExecutor(){
ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
//线程池维护线程的最少数量
poolTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);
//线程池维护线程的最大数量
poolTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
//线程池所使用的缓冲队列
poolTaskExecutor.setQueueCapacity(200);
//线程池维护线程所允许的空闲时间
poolTaskExecutor.setKeepAliveSeconds(30000);
poolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
System.out.println(poolTaskExecutor);
return poolTaskExecutor;
}
}
4.DataSourceConfig.java
@Component
@Configuration
@MapperScan(basePackages = "com.thread.threadtest.dao", sqlSessionTemplateRef = "systemSqlSessionTemplate")
public class DataSourceConfig {
@Bean(name = "systemDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.primary") // application.properteis中对应属性的前缀
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "systemSqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("systemDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
bean.setTypeAliasesPackage("com.thread.threadtest.pojo");
return bean.getObject();
}
@Bean(name = "systemTransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("systemDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "systemSqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("systemSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
5.UserVoController.java
@RestController
@RequestMapping("/user")
public class UserVoController {
@Autowired
private UserVoService userVoService;
@RequestMapping("/submit")
public String submit(String param){
param = userVoService.submit(param);
return param;
}
@RequestMapping("/execute")
public String execute(String param){
param = userVoService.execute(param);
return param;
}
}
6.UserVoService.java
public interface UserVoService {
String submit(String param);
String execute(String param);
}
7.UserVoServiceImpl.java
@Service
public class UserVoServiceImpl implements UserVoService {
@Autowired
private ThreadPoolTaskExecutorConfig threadPoolTaskExecutorConfig;
@Autowired
private UserVoDao userVoDao;
@Override
public String submit(String param) {
Future<String> future = threadPoolTaskExecutorConfig.serviceJobTaskExecutor().submit(new UserVoCallableTask(param));
try {
param = future.get();
} catch (Exception e) {
e.printStackTrace();
return "error";
}
UserVo user = new UserVo();
user.setName(param);
userVoDao.insertUserVo(user);
return param;
}
@Override
public String execute(String param) {
threadPoolTaskExecutorConfig.serviceJobTaskExecutor().execute(new UserVoRunnableTask(param, userVoDao));
return "success";
}
}
8.UserVoDao.java
public interface UserVoDao {
void insertUserVo(UserVo user);
}
9.UserVo.java
public class UserVo {
private int id;
private String ucode;
private String name;
private String sex;
private String pwd;
private int sid;
private String school;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUcode() {
return ucode;
}
public void setUcode(String ucode) {
this.ucode = ucode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
}
10.UserVoCallableTask.java
public class UserVoCallableTask implements Callable<String> {
private String param;
public UserVoCallableTask(String param){
this.param = param;
}
@Override
public String call() throws Exception {
param +="UserVoCallableTask";
int a = 1/0;
return param;
}
}
11.UserVoRunnableTask.java
public class UserVoRunnableTask implements Runnable {
private String param;
private UserVoDao userVoDao;
public UserVoRunnableTask(String param, UserVoDao userVoDao) {
this.param = param;
this.userVoDao = userVoDao;
}
@Override
public void run() {
param += "UserVoRunnableTask";
UserVo user = new UserVo();
user.setName(param);
int a = 1/0;
userVoDao.insertUserVo(user);
}
}
12.ThreadtestApplication
@SpringBootApplication
@ComponentScan(basePackages = {"com.thread.threadtest.*"})
public class ThreadtestApplication {
public static void main(String[] args) {
SpringApplication.run(ThreadtestApplication.class, args);
}
}
13. 요청 인터페이스를 제출
14. 요청 인터페이스 실행 :
15. 요약
1.Callable 만남은 전화를 실행하면 예외가 발생합니다,하지만 실행을 수행 할 때의 Runnable가 발생 예외가 발생하지 않습니다.
넷째, 멀티 스레딩 및 트랜잭션 롤백 :
당신이 트랜잭션에 여러 스레드를 호출하는 경우 위, 예외가 발생하는 인식 할 수없는 주 스레드, 롤백을 트리거 실행되지 않습니다, 예외가 던져 질 것이다 잡은해야 발생 제출할, 그것은 롤백을 유발하지 않습니다. 당신이 멀티 스레드에서 해당 트랜잭션 롤백 호출을 실현해야하는 경우 그것을 어떻게 할까? 이것은 다른 작업의 추가가 필요합니다
1, 트랜잭션 롤백 방법을 제출 : 우리는 결과의 반환을 획득 스레드를 제출 작성 방법을 알고있는 예외를 catch 할 필요가있다, 이상이 수동으로 현재 트랜잭션을 롤백 할 때 우리는 캡처 할 수 있습니다.
(1) 메인 쓰레드 비정상 발생 자식 스레드, 메인 쓰레드에만 롤 정상이다의 setRollbackOnly 비교적 간단한 경우, 직접 주 스레드 예외 캡처 TransactionAspectSupport.currentTransactionStatus (후) ()는 메인 스레드가 될 수 롤백 :
1.1. UserServiceImpl.java
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Autowired
private UserMapper userMapper;
@Override
@Transactional
public String submit(String param) {
Future<String> future = threadPoolTaskExecutor.submit(new UserCallableTask(param,userMapper));
UserDTO user = new UserDTO();
user.setName("我是主线程");
userMapper.insert(user);
try {
param = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return "error";
} catch (ExecutionException e) {
e.printStackTrace();
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return "error";
}
return param;
}
@Override
public String execute(String param) {
threadPoolTaskExecutor.execute(new UserRunnableTask(param,userMapper));
return "success";
}
}
1.2.UserCallableTask.java
public class UserCallableTask implements Callable<String> {
private String param;
private UserMapper userMapper;
public UserCallableTask(String param, UserMapper userMapper){
this.param = param;
this.userMapper = userMapper;
}
@Override
public String call() throws Exception {
param += "UserCallableTask";
UserDTO user = new UserDTO();
user.setName("我是子线程");
userMapper.insert(user);
int a = 1/0;
return param;
}
}
3. 결과
4. 데이터베이스는 메인 스레드 삽입 된 데이터가 아니며 :
메인 스레드 롤백 성공의 설명.
(2) 주 스레드 또는 하위 스레드 예외 메인 스레드, 자식 스레드 모든 롤백 : 롤백 메인 스레드와 자식 스레드, 우리는 메인 스레드를 둘 필요와 아이가 같은 트랜잭션 스레드있다. 메인 스레드에 대한 설명, 자식 스레드가 성공적으로 롤백.
참고 블로그 : https://blog.csdn.net/w_t_y_y/article/details/102817576
다섯째, 말
항상 믿음을 유지!