Spring事务
内容
- spring事务机制:事务抽象、事务传播、事务隔离
- 代码方式和标签方式实现
- JPA和JMS事务实例
Spring事务管理
- 提法统一的API接口支持不同的资源
- 提供声明式事务管理
- 方便的与Spring框架集成
- 多个资源的事务管理、同步
Spring事务抽象
-
PlatformTransactionManager
public interface PlatformTransactionManager { TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException; void commit(TransactionStatus var1) throws TransactionException; void rollback(TransactionStatus var1) throws TransactionException; }
-
TransactionDefinition(事务定义)
public interface TransactionDefinition { //(default) int PROPAGATION_REQUIRED = 0; int PROPAGATION_SUPPORTS = 1; int PROPAGATION_MANDATORY = 2; int PROPAGATION_REQUIRES_NEW = 3; int PROPAGATION_NOT_SUPPORTED = 4; int PROPAGATION_NEVER = 5; // 嵌套 ,只有JDBC 3.0可以使用 int PROPAGATION_NESTED = 6; int ISOLATION_DEFAULT = -1; int ISOLATION_READ_UNCOMMITTED = 1; int ISOLATION_READ_COMMITTED = 2; int ISOLATION_REPEATABLE_READ = 4; int ISOLATION_SERIALIZABLE = 8; int TIMEOUT_DEFAULT = -1; int getPropagationBehavior(); //事务传播机制 int getIsolationLevel(); //隔离级别 int getTimeout(); boolean isReadOnly(); @Nullable String getName(); }
-
TransactionStatus(事务的运行状态)
public interface TransactionStatus extends SavepointManager, Flushable { boolean isNewTransaction(); boolean hasSavepoint(); void setRollbackOnly(); boolean isRollbackOnly(); void flush(); }
Spring事务机制
PlatformTransactionManager的常见实现
- DataSourceTransactionManager
- JpaTransactionManager
- JmsTransactionManager(消息中间件使用)
- JtaTransactionManager
Spring事务实例
实例一(JPA)
内容:
- List item
方式一:代码实现
@Autowired
private PlatformTTransactionManager transactionManager;
public User create(User user){
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setIsolationLevel(ransactionDefinition.ISOLATION_DEFAULT);
def.setPropagationBehavior(ransactionDefinition.PROPAGATION_REQUIRED );
TransactionStatus ts = transactionManager.getTransaction(def);
try{
//TODO
transactionManager.commit(ts);
}catch(Exception e){
transactionManager.rollback(ts);
throw e;
}
}
方式二:标签实现
@Transactional
public User create(User user){
//TODO
}
实例二(JMS)
内容:
- Spring boot中使用JMS
- Spring Boot ActiveMQ starter
- 内置可运行的ActiveMQ服务器
- 实现读写ActiveMQ的事务
JMS基础
Spring JMS Session
- 通过Session进行事务管理
- Session是thread-bound
- 事务上下文:在一个线程中的一个Session
Spring JMS事务类型
- Session管理的事务-原生事务
- 外部的事务管理:JmsTransactionManager、JTA
方式一:JMS实现
Controller
@RestController
@RequestMapping("/api")
public class UserController {
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private UserService userService;
@PostMapping("/message/listen")
public void create(@RequestParam String msg){
jmsTemplate.convertAndSend("user:sql:new",msg);
}
@PostMapping("/message/direct")
public void handler(@RequestParam String msg){
userService.handler(msg);
}
@GetMapping("/message")
public String read(){
jmsTemplate.setReceiveTimeout(2000);
Object obj = jmsTemplate.receiveAndConvert("user:msg:reply");
return String.valueOf(obj);
}
}
Service
@Service
public class UserService {
@Autowired
private JmsTemplate jmsTemplate;
@JmsListener(destination = "user:sql:new")
public void handler(String msg){
String reply = "Reply-" + msg;
jmsTemplate.convertAndSend("user:msg:reply",reply);
if (msg.contains("error")){
throw new RuntimeException("Data error");
}
}
}
说明:
- 请求一:api/message/listen是可以进行事务回滚,但失败会重试多次
- 请求二:api/message/redirt是不可以进行事务回滚
- 原因:JMS是通过session进行事务管理的
方式二:JmsTransactionManager实现
Config
@EnableJms
@Configuration
public class JmsConfig {
@Bean
PlatformTransactionManager transactionManager(ConnectionFactory connectionFactory){
return new JmsTransactionManager(connectionFactory);
}
@Bean
JmsTemplate jmsTemplate(ConnectionFactory connectionFactory){
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(connectionFactory);
return jmsTemplate;
}
@Bean
JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory,
PlatformTransactionManager transactionManager,
DefaultJmsListenerContainerFactoryConfigurer configurer){
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory,connectionFactory);
factory.setTransactionManager(transactionManager);
return factory;
}
}
Controller
@RestController
@RequestMapping("/api")
public class UserController {
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private UserService userService;
@PostMapping("/message/listen")
public void create(@RequestParam String msg){
jmsTemplate.convertAndSend("user:sql:new",msg);
}
@PostMapping("/message/direct")
public void handler(@RequestParam String msg){
userService.handler(msg);
}
@GetMapping("/message")
public String read(){
jmsTemplate.setReceiveTimeout(2000);
Object obj = jmsTemplate.receiveAndConvert("user:msg:reply");
return String.valueOf(obj);
}
}
Service
@Service
public class UserService {
@Autowired
private JmsTemplate jmsTemplate;
@Transactional
@JmsListener(destination = "user:sql:new")
public void handler(String msg){
String reply = "Reply-" + msg;
jmsTemplate.convertAndSend("user:msg:reply",reply);
if (msg.contains("error")){
throw new RuntimeException("Data error");
}
}
}
说明:
- 请求一:api/message/listen是可以进行事务回滚,失败不会重试
- 请求二:api/message/redirt是可以进行事务回滚