-
方式一TransactionTemplate
package luck.spring.tx;
@Import(DatabaseConfig.class)
@Configuration
public class Demo {
private final TransactionTemplate transactionTemplate;
private final JdbcTemplate jdbcTemplate;
public Demo(PlatformTransactionManager transactionManager, JdbcTemplate jdbcTemplate) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
this.jdbcTemplate = jdbcTemplate;
this.initTransactionTemplate();
}
public void initTransactionTemplate() {
// 设置隔离级别
this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
// 30s
this.transactionTemplate.setTimeout(30);
// 设置传播行为
this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
}
@PostConstruct
public void init() {
// 编程式事务
transactionTemplate.executeWithoutResult(status -> {
jdbcTemplate.execute("insert into jdbc(id, name) value (DEFAULT,'" + RandomUtil.randomString(5) + "')");
// 默认需要回滚
if (RandomUtil.randomInt(0, 10) > 4) {
// 标记当前事务需要回滚
status.setRollbackOnly();
}
});
}
@SneakyThrows
public static void main(String[] args) {
new AnnotationConfigApplicationContext(Demo.class);
}
}
-
方式二TransactionOperator(响应式编程)
public class SimpleService implements Service {
private final TransactionalOperator transactionalOperator;
public SimpleService(ReactiveTransactionManager transactionManager) {
this.transactionOperator = TransactionalOperator.create(transactionManager);
}
public Mono<Object> someServiceMethod() {
Mono<Object> update = doSomething();
return update.then(resultOfUpdateOperation2).as(transactionalOperator::transactional);
}
}
-
方式三TransactionManager
package luck.spring.tx;
import cn.hutool.core.util.RandomUtil;
import lombok.SneakyThrows;
import luck.spring.config.DatabaseConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.PostConstruct;
@Import(DatabaseConfig.class)
@Configuration
public class Demo {
private final JdbcTemplate jdbcTemplate;
private final PlatformTransactionManager transactionManager;
public Demo(PlatformTransactionManager transactionManager,JdbcTemplate jdbcTemplate)
{
this.transactionManager = transactionManager;
}
@PostConstruct
public void init() {
// 编程式事务
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setName("luck-tx-name");
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
definition.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
definition.setTimeout(30);
TransactionStatus status = transactionManager.getTransaction(definition);
try {
jdbcTemplate.execute("insert into jdbc(id, name) value (DEFAULT,'" + RandomUtil.randomString(5) + "')");
// 默认需要回滚
if (RandomUtil.randomInt(0, 10) > 4) {
// 标记当前事务需要回滚
System.out.println(1 / 0);
}
} catch (Exception ex) {
transactionManager.rollback(status);
throw ex;
}
transactionManager.commit(status);
}
@SneakyThrows
public static void main(String[] args) {
new AnnotationConfigApplicationContext(Demo.class);
}
}
总结
其实,第三种和第一种底层实现是完全一样的,transactionTemplate是对transactionManager的进一步封装,我们最终操作的都是通过transactionManager来获取到事务状态TransactionStatus,这个事务状态决定了最终事务的走向