您的位置:首页 > 编程语言 > Java开发

Spring TransactionTemplate + Mysql事务理解

2017-07-10 13:41 423 查看
Mysql事务使用

autocommit说明

事务使用

案例

JDBC事务使用

TransactionTemplate对事务的使用

真实场景

Mysql事务使用

autocommit说明

在Mysql有个属性叫做autocommit,表示是否自动提交事务,默认值是1,表示true,所以我们一般使用sql语句,执行完就立即更新数据库了。如果set auotcommit=0之后sql语句执行完之后必须执行commit才能使数据持久化。

事务使用

mysql可以把一组sql操作放在同一事务里,要么全部执行,要么一个都不执行不执行。
1.开始一个事务start transaction,begin;
2.回滚事务rollback;
3.提交一个事务commit;
4.创建一个保存点,可以指定回滚到该点savepoint identifier;
5.删除一个事务的保存点release savepoint identifier;
6.把事务回滚到标记点 rollback to identifier。如:
begin
sql1,sql2,sql3,sql4......
commit(或rollback)


案例

begin;  开始一个事务
update score set score=40 where scoreid=1;
savepoint s1;  创建保存点
update score set score=50 where scoreid=1;
select * from score;
rollback to savepoint s1;  回滚到保存点
select * from score;
commit;  提交一个事务


备注:set auotcommit=0后,所有的sql操作都是事务,需要commit;begin开始的只是当前一组sql操作是事务。

JDBC事务使用

try{
connection.setAutoCommit(false);  //不自动提交
......执行jdbc代码
sql1,sql2,sql3
connection.commit();
}catch(Exception e){
connection.roolback();
}finally{
//清理资源
connection.setAutoCommit(true);  //改回自动提交
}


TransactionTemplate对事务的使用

1.transactionTemplate.execute里会会通过PlatformTransactionManager.getTransaction获取一个TransactionStatus实例,在获取该实例方法中,会调用DataSourceTransactionManager的doBegin方法,该方法会执行connection.setAutoCommit(false);

2.执行一组sql的操作

3.执行PlatformTransactionManager.commit提交事务

4.如果有异常transactionStatus.rollbackOnException回滚事务

真实场景

1.商品扣减库存、插入幂等表记录。
private void reduceStockTransaction(StockChangeDTO stockChangeDTO) {
Exception e = transactionTemplate.execute(transactionStatus -> {
try {
int rows = skuStockBreakDOMapper.reduceStock(stockChangeDTO.getSkuId(), stockChangeDTO.getStockBreak(),
stockChangeDTO.getAmount(), new Date());
if (rows <= 0) {
ServiceException se = new ServiceException(ErrorCode.ITEM_SELL_STOCK_ERROR);
se.setSuppressLogging(true);
throw se;
}
SkuStockJournalDO skuStockJournalDO = ItemConverter.toSkuStockJournalDO(stockChangeDTO,
ItemStockTransType.SELL);
skuStockJournalDOMapper.insertJournal(skuStockJournalDO);
} catch (Exception ex) {
transactionStatus.setRollbackOnly();
return ex;
}
return null;
});

if (e == null) {
handleEmptyStock(stockChangeDTO.getSkuId(), stockChangeDTO.getStockBreak());
} else {
if (e instanceof ServiceException)
throw (ServiceException) e;
throw new ServiceException(ErrorCode.REDUCE_STOCK_ERROR, e);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息