@Transactional
注解可以设置参数。
readOnly
:true只读事务,false读写事务,增删改要设为false,查询设为true。
timeout:
设置超时时间单位秒,在多长时间之内事务没有提交成功就自动回滚,-1表示不设置超
时时间。
rollbackFor
:当出现指定异常进行事务回滚。
noRollbackFor
:当出现指定异常不进行事务回滚。
注意:Spring的事务只会对Error异常
和RuntimeException异常
及其子类进行事务回顾,其他的异常类型是不会回滚的。
isolation
设置事务的隔离级别:
DEFAULT
:默认隔离级别, 会采用数据库的隔离级别
READ_UNCOMMITTED
: 读未提交
READ_COMMITTED
: 读已提交
REPEATABLE_READ
: 重复读取
SERIALIZABLE
: 串行化
propagation
属性设置事务的传播。
比如:在前面的转案例的基础上添加新的需求,完成转账后记录日志。
LogDao接口:
public interface LogDao {
@Insert("insert into tbl_log (info,createDate) values(#{info},now())")void log(String info);
}
LogService接口与实现类:
public interface LogService {void log(String out, String in, Double money);
}
@Service
public class LogServiceImpl implements LogService {@Autowiredprivate LogDao logDao;@Transactionalpublic void log(String out,String in,Double money ) {logDao.log("转账操作由"+out+"到"+in+",金额:"+money);}
}
修改后的转账业务:
public interface AccountService {/*** 转账操作* @param out 传出方* @param in 转入方* @param money 金额*///配置当前接口方法具有事务public void transfer(String out,String in ,Double money) ;
}@Service
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountDao accountDao;@Autowiredprivate LogService logService;@Transactionalpublic void transfer(String out,String in ,Double money) {try{accountDao.outMoney(out,money);accountDao.inMoney(in,money);}finally {logService.log(out,in,money);}}
}
看起来可能没什么问题,但是一旦转账业务之间出现异常,转账失败事务回滚后日志记录能保存下来吗?很明显因为日志与转账属于同一个事务,所以会一起回滚。这时候就需要propagation
属性,将日志添加到一个新的业务之中。即修改事务传播行为(事务协调员对事务管理员所携带事务的处理态度)。
@Service
public class LogServiceImpl implements LogService {@Autowiredprivate LogDao logDao;//propagation设置事务属性:传播行为设置为当前操作需要新事务@Transactional(propagation = Propagation.REQUIRES_NEW)public void log(String out,String in,Double money ) {logDao.log("转账操作由"+out+"到"+in+",金额:"+money);}
}