使用原因:
公司需要写一个定时任务,涉及增改查操作,
定时将前端页面配置的字典数据(标签数据)同步到数据库特定的表(标签表)
查询字典表数据
字典有,数据库表没有=新增
都有,判断名称,名称不同修改
【观察其他定时任务,采用return Result写法,异常-1,正常1,所以排除@Transactional,因为异常时return,无法回滚(抛异常会跟相同功能的写法背离),所以采用手动事务处理】
备注:
范围要小,在增删改的地方,创建手动事务,异常里做回滚
原因:上来就手动事务,或者手动事务开启过早,容易出现长事务问题
写法如下:
=====================正常情况下用这一坨=============================
=====================扩展作为全面了解使用===========================
=====================注解写法看第二段===============================
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
@Resource
private PlatformTransactionManager transactionManager;
// 1:定义事务属性
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
try {
//2:数据库操作
//新增
//更新
//删除
........
} catch (Exception e) {
// 【出现问题】3:手动回滚事务
transactionManager.rollback(status);
log.info("数据批量插入及更新异常,异常消息:{},完整异常:{}", e.getMessage(), e);
}
// 【没问题】4:手动提交事务
transactionManager.commit(status);
==============================@Transactional写法====================
==============================@Transactional写法====================
==============================@Transactional写法====================
@Transactional(
propagation = Propagation.REQUIRED, //传播行为
isolation = Isolation.READ_COMMITTED, //隔离级别
timeout = 30, //超时时间,超时自动回滚
readOnly = false //是否只读,ture不可写,false可写
)
===============================扩展=================================
===============================扩展=================================
===============================扩展=================================
// 创建一个默认事务定义对象
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// 设置传播行为为 PROPAGATION_REQUIRED:
// - 如果当前没有事务,就新建一个;
// - 如果已经存在事务,就加入该事务(这是默认值)
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
// 可选的其他传播行为如下(取消注释即可使用):
// def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 总是新建事务,并挂起已有事务
// def.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); // 有事务就用,没事务就不用
// def.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);// 不用事务,挂起已有事务
// def.setPropagationBehavior(TransactionDefinition.PROPAGATION_NEVER); // 不能有事务,否则抛异常
// def.setPropagationBehavior(TransactionDefinition.PROPAGATION_MANDATORY); // 必须有事务,否则抛异常
// def.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED); // 嵌套事务,可独立提交或回滚
// 设置隔离级别为 ISOLATION_READ_COMMITTED:
// - 只能读取已提交的数据,避免脏读(读已提交)
def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
// 可选的其他隔离级别如下(取消注释即可使用):
// def.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT); // 使用数据库默认级别(如 MySQL 是 REPEATABLE_READ) 【读已提交】
// def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED); // 允许脏读(最低隔离) 【读未提交】
// def.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ); // 避免脏读和不可重复读 【可重复读】
// def.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); // 最高隔离,完全串行化执行 【串行化】
// 设置事务最大持续时间为30秒,超时自动回滚
def.setTimeout(30);
// 设置事务是否为只读:
// - true:表示事务中不会修改数据,有助于性能优化(如查询操作)
// - false:允许读写操作(默认值)
def.setReadOnly(false);
// 设置事务名称,用于日志、调试或监控识别
def.setName("MyCustomTx");
// 开始事务,并获取事务状态对象
TransactionStatus status = transactionManager.getTransaction(def);
try {
// 【在这里编写你的业务逻辑】
// 比如执行多个数据库操作 jdbcTemplate.update(...) 等
// 提交事务:如果没有异常,提交所有更改
transactionManager.commit(status);
} catch (Exception e) {
// 出现异常:回滚事务,撤销之前的操作
transactionManager.rollback(status);
throw e; // 可选择重新抛出异常以便上层处理
}