事务的范围比锁的范围大

请看场景:

复制代码
@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):使用方法获取动态对象。

相关推荐
2401_8654396320 分钟前
mysql如何处理升级后的身份认证兼容性_mysql_native_password配置
jvm·数据库·python
zopple20 分钟前
四大编程语言对比:PHP、Python、Java与易语言
java·python·php
lhbian21 分钟前
PHP、C++和C语言对比:哪个更适合你?
android·数据库·spring boot·mysql·kafka
NotFound48621 分钟前
Flask项目目录怎么分_MVC架构在Flask应用中的常见目录树
jvm·数据库·python
小陈phd24 分钟前
电商智能客服智能体——基于LangChain的电商智能客服 Agent 架构设计与实现(二)
数据库·microsoft·langchain
2401_8971905526 分钟前
JavaScript对象浅拷贝:Object-assign的合并规则
jvm·数据库·python
Shorasul31 分钟前
如何用 fill 配合 map 初始化一个填充了不同对象的数组
jvm·数据库·python
kaikaile199533 分钟前
C# 文件编码转换工具
开发语言·c#
weixin_5860614634 分钟前
golang如何使用go-redis客户端_golang go-redis客户端使用教程
jvm·数据库·python
逍遥德42 分钟前
Java 锁(线程间)和数据库锁(事务间)对比详解
java·数据库·sql·高并发·锁机制