-
Notifications
You must be signed in to change notification settings - Fork 328
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
195 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>spring-boot</artifactId> | ||
<groupId>com.git.hui.boot</groupId> | ||
<version>0.0.1-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>transaction-manager</artifactId> | ||
|
||
<properties> | ||
<maven.compiler.source>8</maven.compiler.source> | ||
<maven.compiler.target>8</maven.compiler.target> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-jdbc</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-web</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>mysql</groupId> | ||
<artifactId>mysql-connector-java</artifactId> | ||
</dependency> | ||
</dependencies> | ||
</project> |
46 changes: 46 additions & 0 deletions
46
spring-boot/100-transaction-manager/src/main/java/com/git/hui/boot/trans/Application.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package com.git.hui.boot.trans; | ||
|
||
import com.git.hui.boot.trans.service.DemoService; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
/** | ||
* @author YiHui | ||
* @date 2023/6/14 | ||
*/ | ||
@RestController | ||
@SpringBootApplication | ||
public class Application { | ||
@Autowired | ||
private DemoService demoService; | ||
|
||
@GetMapping(path = "/") | ||
public String preExecute() { | ||
try { | ||
demoService.transExecute(true); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
return e.getMessage(); | ||
} | ||
return "ok"; | ||
} | ||
|
||
@GetMapping(path = "/out") | ||
public String outExecute() { | ||
try { | ||
demoService.outTransExecute(); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
return e.getMessage(); | ||
} | ||
return "ok"; | ||
} | ||
|
||
|
||
public static void main(String[] args) { | ||
SpringApplication.run(Application.class); | ||
} | ||
} |
104 changes: 104 additions & 0 deletions
104
...oot/100-transaction-manager/src/main/java/com/git/hui/boot/trans/service/DemoService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package com.git.hui.boot.trans.service; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.jdbc.core.JdbcTemplate; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import org.springframework.transaction.support.TransactionSynchronization; | ||
import org.springframework.transaction.support.TransactionSynchronizationManager; | ||
import org.springframework.util.Assert; | ||
|
||
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
/** | ||
* @author YiHui | ||
* @date 2023/6/14 | ||
*/ | ||
@Slf4j | ||
@Service | ||
public class DemoService { | ||
@Autowired | ||
private JdbcTemplate jdbcTemplate; | ||
|
||
private ThreadLocal<String> cache = new ThreadLocal<>(); | ||
private AtomicInteger cnt = new AtomicInteger(1); | ||
|
||
@Autowired | ||
private DemoService demoService; | ||
|
||
@Transactional(rollbackFor = Exception.class) | ||
public void outTransExecute() throws InterruptedException { | ||
String name = "2灰灰" + cnt.getAndAdd(1); | ||
log.info("{}-out写入缓存: {}", Thread.currentThread(), name); | ||
jdbcTemplate.execute("insert into money (`name`, `money`) values ('" + name + "', " + cnt.get() + ");"); | ||
|
||
new Thread(new Runnable() { | ||
@Override | ||
public void run() { | ||
demoService.transExecute(false); | ||
} | ||
}).start(); | ||
|
||
// 验证外部事务回滚,子线程的事务是否也会回滚(判断两个事务是否是同一个) | ||
log.info("外部执行完毕!"); | ||
Thread.sleep(2000); | ||
Assert.isTrue(Math.random() > 0.5, "外部事务回滚"); | ||
} | ||
|
||
/** | ||
* 事务提交前执行某些操作 | ||
* - 再同一个线程中执行,不过注册的事务提交前执行任务,会后置到这个方法执行完,再然后在相同的线程中执行 | ||
*/ | ||
@Transactional(rollbackFor = Exception.class) | ||
public void transExecute(boolean hasException) { | ||
String name = "一灰灰" + cnt.getAndAdd(1); | ||
log.info("{}-外部写入缓存: {}", Thread.currentThread(), name); | ||
cache.set(name); | ||
jdbcTemplate.execute("insert into money (`name`, `money`) values ('" + name + "', " + cnt.get() + ");"); | ||
registryBeforeCommitOrImmediatelyRun(new Runnable() { | ||
@Override | ||
public void run() { | ||
String last = cache.get(); | ||
log.info("{}-缓存中的新增数据: {}", Thread.currentThread(), last); | ||
try { | ||
Thread.sleep(1000); | ||
} catch (InterruptedException e) { | ||
throw new RuntimeException(e); | ||
} | ||
|
||
if (hasException) { | ||
// 让这里概率性失败,从而模拟事务回滚的场景 | ||
Assert.isTrue(Math.random() > 0.5f, "模拟事务回滚!"); | ||
} | ||
} | ||
}); | ||
|
||
log.info("transExecute 执行完毕!"); | ||
} | ||
|
||
|
||
/** | ||
* 注册事务回调-事务提交前执行,如果没在事务中就立即执行 | ||
* | ||
* @param runnable | ||
*/ | ||
public static void registryBeforeCommitOrImmediatelyRun(Runnable runnable) { | ||
if (runnable == null) { | ||
return; | ||
} | ||
// 处于事务中 | ||
if (TransactionSynchronizationManager.isSynchronizationActive()) { | ||
// 等事务提交前执行,发生错误会回滚事务 | ||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { | ||
@Override | ||
public void beforeCommit(boolean readOnly) { | ||
runnable.run(); | ||
} | ||
}); | ||
} else { | ||
// 马上执行 | ||
runnable.run(); | ||
} | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
spring-boot/100-transaction-manager/src/main/resources/application.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
## log | ||
logging.file=logs/info.log | ||
logging.file.max-history=2 | ||
logging.file.max-size=1GB | ||
|
||
## DataSource | ||
spring.datasource.url=jdbc:mysql://localhost:3306/story?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2b8 | ||
spring.datasource.driver-class-name= com.mysql.cj.jdbc.Driver | ||
spring.datasource.username=root | ||
#spring.datasource.password= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters