搭建好FastDFS之后,测试了下文件上传下载,没啥问题。然后不经意间发现自己原来之前MySQL操作忘记配置事务了,就顺便配置下。
下面先讲讲自己为啥这么配,下面再贴自己事务的配置类
-
事务级别选择
MySQL默认的事务级别是可重复读(repeatable-read),但是这种模式下,如果SQL没有命中索引,就会锁表。而比这个事务低一个级别的不可重复读(read-committed)在没有命中索引的时候,会放弃对当前扫描到的数据行的S/X锁,只对不符合索引条件的进行S/X锁。
所以建议分布式事务使用RC不可重复读,避免高并发的表锁拖累响应速度。
推荐阅读文章,mysql的默认隔离级别 和 mysql数据库隔离级别及其原理、Spring的7种事物传播行为
-
据说Spring会对只读事务会做一些优化,建议get类型的方法事务指定read-only=“true”
/** * A boolean flag that can be set to {@code true} if the transaction is * effectively read-only, allowing for corresponding optimizations at runtime. * <p>Defaults to {@code false}. * <p>This just serves as a hint for the actual transaction subsystem; * it will <i>not necessarily</i> cause failure of write access attempts. * A transaction manager which cannot interpret the read-only hint will * <i>not</i> throw an exception when asked for a read-only transaction * but rather silently ignore the hint. * @see org.springframework.transaction.interceptor.TransactionAttribute#isReadOnly() * @see org.springframework.transaction.support.TransactionSynchronizationManager#isCurrentTransactionReadOnly() */ boolean readOnly() default false;
-
事务传播行为选择
建议改变数据的操作update/insert/delete采用”
PROPAGATION_REQUIRED
“; 建议不改变数据的操作update/insert/delete采用”
PROPAGATION_SUPPORTS
“; 网上也有用
PROPAGATION_NOT_SUPPORTED
而不是PROPAGATION_SUPPORTS
的。我个人是觉得前者挂起事务对增删改的事务流程效率有一定影响。
····而且挂起事务,虽然前面update锁定的行是排他锁(X锁)使得我select无法加共享锁(S锁),但是不加锁不代表我获取不到数据,只不过不能再加S锁而已。平时加S锁主要就是为了不能在上面继续加X锁。我select获取到的还是修改后的(本地测试了,没能获取修改前的)。更何况挂起事务=另开一个连接线程 -> 浪费连接数。
····要是读频繁导致写不进入,可以考虑用乐观锁代替事务加上去的S锁,这样不会锁住数据,但是如果乐观锁验证version不同就不读取的话,那么可能出现写频繁导致读不到的情况(当然也可以设置自旋,直到version两次读取相同,返回结果,但是同样可能导致长时间自旋,浪费资源)。 -
事务最好在impl实现类上使用@Transactional ,而不是在接口上。如果在接口上使用@Transactional,只有使用基于接口的代理时才会生效。
且
@Transactional
只对public方法生效(不是pulic不生效也不会报错) -
配置类
// 启动类 添加注解
@EnableTransactionManagement // 开启事务支持
public class XXXXXApplication {
.....
}