I.背景
1.我々はそれの彼の具体的例を外れ、基本的な理論的知識の多くの前で説明し、今、私たちは小さな栗のいくつかの簡単なポイントを起動し、前に学ぶために私たちの基本を統合します。
2.その後、我々はそれを説明するために開始し、騒ぎ、その後、私たちはよく、今日の私たちの小さなケースを説明し始め、継続する場合を説明するために小型の最初の部分を持っています。
第二に、プロジェクトマップ
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は、トランザクションのロールバック方法を提出:私たちは、結果のリターンを得ることにスレッドを提出するsumbitの方法を知っている例外をキャッチする必要があり、異常が手動で現在のトランザクションをロールバックするとき、我々はキャプチャすることができます。
直接メインスレッド例外捕捉TransactionAspectSupport.currentTransactionStatus()setRollbackOnlyメソッド()の後に、比較的単純な場合、;ロールバックメインスレッドとすることができる:(1)メインスレッドは、正常、異常発生の子スレッドは、メインスレッドのみロールバックである
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.結果
前記データベースは、メインスレッド挿入データはありません。
メインスレッドのロールバックの成功の説明。
(2)、メインスレッドまたはサブスレッドの例外は、メインスレッド、子スレッドのすべてのロールバック:ロールバックメインスレッドと子スレッド間、私たちは、メインスレッドと子スレッドに同じトランザクションを配置する必要があります。メインスレッドの説明は、子スレッドが正常にロールバックされました。
参考ブログ:https://blog.csdn.net/w_t_y_y/article/details/102817576
第五に、の終わり
常に信念を貫きます!!!