事务的范围比锁的范围大

请看场景:

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

相关推荐
奇树谦6 分钟前
《现代 Key-Value 数据库原理:从 B+Tree 到 LSM Tree》-第三篇:LMDB 深度解析二
数据库·oracle·lsm-tree
提笔了无痕6 分钟前
Agent 上下文管理详解、Context设计与构建
数据库·oracle·agent·context
xieliyu.11 分钟前
Java 文件IO :File 文件类、字节流、字符流讲解
java·ide·笔记·javaee
用户71522873814113 分钟前
数据库字段冗余,真的只是用空间换时间吗?
数据库
Hhy_110718 分钟前
【从零开始学数据结构 ⑥】:二叉树之堆——打破规则的优先队列
c语言·开发语言·数据结构·学习·visual studio
沉下去,苦磨练!21 分钟前
Human‑in‑the‑Loop
数据库·oracle
云烟成雨TD21 分钟前
Micrometer 系列【28】Spring Boot Actuator | 其他指标速览
java·spring boot·云原生
meilindehuzi_a24 分钟前
深入理解 Linux 进程地址空间:从虚拟内存、页表映射到 fork 写时拷贝与 VMA 管理
java·linux·服务器
莫得感情 o30 分钟前
设计模式 13 · 桥接模式
java·设计模式·桥接模式
吠品31 分钟前
Java中实现拓扑排序的两种方式:Kahn算法和DFS
java·数据库·notepad++