@Transactional注解支持9个属性的设置,这里只讲解其中使用较多的三个属性:readOnly、propagation、isolation。其中propagation属性用来枚举事务的传播行为,isolation用来设置事务隔离级别,readOnly进行读写事务控制。
@Service
@Transactional(readOnly = true)
public class AppTradeRec2Service extends BaseService {
@Autowired
private AppTradeRecDao appTradeRecDao;
@Autowired
private ConsInfoDao consInfoDao;
@Transactional(readOnly = false)
public void payCharge(TradeRec tradeRec) {
User usr = UserUtils.getUser();
ConsInfo cons = consInfoDao.getByUser(usr.getId());
//修改交易记录
tradeRec.setPayBefore(cons.getAccountAmt());
tradeRec.setPayAfter(cons.getAccountAmt() - tradeRec.getRcvAmt());
tradeRec.setIsPay("99");
appTradeRecDao.save(tradeRec);
//修改账户余额
cons.setAccountAmt(cons.getAccountAmt() - tradeRec.getRcvAmt());
consInfoDao.save(cons);
}
}
一、readOnly读写事务控制
readOnly=true表明所注解的方法或类只是读取数据。
readOnly=false表明所注解的方法或类是增加,删除,修改数据。
二、isolation事务隔离级别
我们在使用事务过程中,通常会发生以下三种情况:
1、脏读(dirty read):当一个事务读取另一个事务尚未提交的修改时,产生脏读。
2、不可重复读(non-repeatable read):同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读。
3、幻像读(phantom read):同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读。
针对上述三种情况,Spring提供了5种事务隔离级别予以解决:
1、DEFAULT默认级别
DEFAULT为数据源(数据库)的默认隔离级别,以目前常用的MySQL为例,默认的隔离级别通常为REPEATABLE_READ。
2、READ_UNCOMMITTED未授权读取级别
这是最低的隔离级别,一个事务能读取到别的事务未提交的更新数据,很不安全,可能出现丢失更新、脏读、不可重复读、幻读。
3、READ_COMMITTED授权读取级别
以操作同一行数据为前提,读事务允许其他读事务和写事务,未提交的写事务禁止其他读事务和写事务。此隔离级别可以防止更新丢失、脏读,但不能防止不可重复读、幻读。此隔离级别可以通过“瞬间共享读锁”和“排他写锁”实现。
4、REPEATABLE_READ可重复读取级别
保证同一事务中先后执行的多次查询将返回同一结果,不受其他事务影响。以操作同一行数据为前提,读事务禁止其他写事务,但允许其他读事务,未提交的写事务禁止其他读事务和写事务。此隔离级别可以防止更新丢失、脏读、不可重复读,但不能防止幻读。










