tips:
- Transactional注解必须用在public方法上
- spring aop依赖于aspectjweaver
- 使用AopContext.currentProxy必须在启动类上加@EnableAspectJAutoProxy(exposeProxy = true)
同一个类调用不生效的情况如下
@Component
public class TestService {
@Autowired
JdbcTemplate jdbcTemplate;
// @Transactional(rollbackFor = Exception.class) 这里没加事务
public void contextLoads() {
jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 1});
// ((TestService)AopContext.currentProxy()).test();
this.test(); // 这里直接调用,此时test异常了也不会回滚
}
@Transactional(rollbackFor = Exception.class)
public void test() {
jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 2});
int a = 1/0;
}
}
- 使用TransactionAspectSupport
@Transactional(rollbackFor = Exception.class)
public void contextLoads() {
jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 1});
try {
// ((TestService)AopContext.currentProxy()).test();
this.test();
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
@Transactional(rollbackFor = Exception.class)
public void test() {
jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 2});
int a = 1/0;
}
- 自己抛出RuntimeException
@Transactional(rollbackFor = Exception.class)
public void contextLoads() {
jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 1});
try {
// ((TestService)AopContext.currentProxy()).test();
this.test();
} catch (Exception e) {
// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
throw new RuntimeException();
}
}
@Transactional(rollbackFor = Exception.class)
public void test() {
jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 2});
int a = 1/0;
}
- 使用AopContext.currentProxy
@Transactional(rollbackFor = Exception.class)
public void contextLoads() {
jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 1});
((TestService)AopContext.currentProxy()).test();
}
@Transactional(rollbackFor = Exception.class)
public void test() {
jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 2});
int a = 1/0;
}
- 不用声明式事务,手动提交和回滚
public class TestService {
@Autowired
JdbcTemplate jdbcTemplate;
@Autowired
ObjectMapper objectMapper;
@Autowired
DataSourceTransactionManager dataSourceTransactionManager;
@Autowired
TransactionDefinition transactionDefinition;
// @Transactional(rollbackFor = Exception.class) // 这里没加事务
public void contextLoads() {
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
try {
jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 1});
this.test();
int a = 1/0;
dataSourceTransactionManager.commit(transactionStatus);
} catch (Exception e) {
System.out.println(e);
// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
dataSourceTransactionManager.rollback(transactionStatus);
String a = null;
try {
a = objectMapper.writeValueAsString(e);
} catch (JsonProcessingException ex) {
ex.printStackTrace();
}
jdbcTemplate.update("update localtest set attr3=? where id=?", new Object[]{a, 1});
}
}
@Transactional(rollbackFor = Exception.class)
public void test() {
jdbcTemplate.update("update localtest set attr1=? where id=?", new Object[]{"aaaa", 2});
}
}