事务的范围比锁的范围大

请看场景:

复制代码
@Servicepublic class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public synchronized void isertUser4(User user) {
// 实际中的具体业务......
userMapper.insertUser(user);
}
}

当我们在数据库插入数据时,要求一个用户只能出现一次,即如果这个用户不存在则插入,不存在则更新。当我们用压测测试这段代码,会发现数据库中有两条以上的同一个用户,这与我们要求的只有一个用户不同。

原因:因为事务的范围比锁的范围大,当我们执行完这个方法,锁已经释放,由其他线程拿到这个锁来重新执行这段代码,但是这个时候,事务的内容还没有写入数据库,我们第二个锁进来判断数据库是否有值判断的肯定是为空,这第二个线程就会又进行插入,而不是进行修改。

解决方法:在调用事务方法的地方加锁,这样保证锁的范围比事务的范围大。

可能产生新的问题:

如果是在同一类当中,直接在加锁的地方调用这个类的另外一个方法(增加了事务的方法),这样是属于this调用。不是动态调用则事务的不起作用。

解决方法:使用动态调用

(1):自己依赖自己,自己将自己自动注入。

(2):使用方法获取动态对象。

相关推荐
独自破碎E3 分钟前
JDK版本的区别
java·开发语言
谦宸、墨白15 分钟前
从零开始学C++:二叉树进阶
开发语言·数据结构·c++
建群新人小猿36 分钟前
陀螺匠企业助手—个人简历
android·大数据·开发语言·前端·数据库
悟空码字1 小时前
SpringBoot深度整合高德地图,构建高性能位置服务
java·springboot·高德地图·编程技术·后端开发
千金裘换酒1 小时前
栈和队列定义及常用语法 LeetCode
java·开发语言
小毅&Nora1 小时前
【后端】【Redis】② Redis事务管理全解:从“购物车结算“到“银行转账“,一文彻底掌握事务机制
数据库·redis·事务
be or not to be1 小时前
JavaScript 对象与原型
开发语言·javascript·ecmascript
0x531 小时前
JAVA|智能无人机平台(二)
java·开发语言·无人机
JH30731 小时前
SpringBoot自定义启动banner:给项目加个专属“开机画面”
java·spring boot·后端
嵌入小生0072 小时前
基于Linux系统下的C语言程序错误及常见内存问题调试方法教程(嵌入式-Linux-C语言)
linux·c语言·开发语言·嵌入式·小白·内存管理调试·程序错误调试