SpringBoot整合JTA事务管理
2019-05-17 本文已影响0人
employeeeee
JTA
- TranscationManager
- XARescource
- XID
缺点
- 两阶段提交
- 事务时间太长 锁数据的时间太长
- 低性能 低吞吐量
使用Springboot整合JTA 进行单数据源的测试
maven 引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
spring-boot 会配置好jta的manager之类的东西 十分方便 直接启动就可以了 为了测试方便 单数据源直接使用的H2数据库和JPA的方式
@Entity(name = "student")
public class Student {
@Id
@GeneratedValue
private Long id;
@Column(name = "username",length = 6)
private String stuname;
private String password;
private String role;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
public interface StudentDao extends JpaRepository<Student,Long> {
}
@Service
public class StudentTsInAnnotation {
@Autowired
public StudentDao studentDao;
@Transactional
public void save(Student student){
studentDao.save(student);
}
public List<Student> getAll(Student student){
return studentDao.findAll();
}
}
@RestController
@RequestMapping("/test/jta")
public class StudentController {
@Resource
private StudentTsInAnnotation studentTsInAnnotation;
@RequestMapping("/save")
public void save(){
Student student = new Student();
student.setId(1000L);
student.setStuname("wang");
student.setPassword("12345");
student.setRole("user");
Student student1 = new Student();
student1.setId(1000L);
student1.setStuname("krisWuuuuuuuuuuu");
student1.setPassword("12345");
student1.setRole("user");
studentTsInAnnotation.save(student);
studentTsInAnnotation.save(student1);
}
}
启动项目进行测试 因为已经给Student名称的长度设置为6 所以在使用save
的时候回出现报错 然后看一下日志 会不会出现回滚
使用JTA管理数据库以及MQ事务
测试的思路是用户通过url向MQ发送一条信息 MQ的监听方法中 会有一个保存用户的方法 然后保存用户后 会向MQ返回一条信息。然后如果名称中包含了kris
那么就会执行Error
的方法,然后查询所有用户 来测试是否进行了回滚
@JmsListener(destination = "student:msg:send")
public void sendMsgAndSave(String stuName){
Student student = new Student();
student.setStuname(stuName);
student.setPassword("123456");
student.setId(1000L);
student.setRole("user");
studentDao.save(student);
if (stuName.contains("kris")){
creatError();
}
jmsTemplate.convertAndSend("student:msg:reply","用户保存的用户名称为:" + stuName);
}
public void creatError(){
throw new RuntimeException();
}
@Transactional
@RequestMapping("/getUser")
public List<Student> getUser(){
return studentDao.findAll();
}
@Transactional
@RequestMapping("/getMsg")
public String getMsg() {
jmsTemplate.setReceiveTimeout(2000);
return String.valueOf(jmsTemplate.receiveAndConvert("student:msg:reply"));
}
@Transactional
@RequestMapping("/sendMsgAndSave")
public void sendMsgAndSave(@RequestParam String stuName){
jmsTemplate.convertAndSend("student:msg:send","用户准备保存一条记录"+stuName);
}
使用JTA管理事务的时候 每一个controller方法 都需要在一个事务中 不然就会报错 所以要在上边加上
@Transactional