9-23 老师为什么没有遇到事务的问题

来源:9-23 websocket新增好友类型联调

学东西要快

2019-03-29

这是同意好友申请的方法A

@Transactional
    public ServerResponse acceptFriendRequest(Long acceptUserId, Long sendUserId) {
        // 通过好友请求
        // 1. 保存好友
        saveFriend(acceptUserId, sendUserId);
        // 2. 逆向保存好友
        saveFriend(sendUserId, acceptUserId);
        // 3. 删除申请好友记录
        deleteFriendRequest(acceptUserId, sendUserId);

        // 使用websocket主动推送消息到请求发起者, 更新他的通讯录
        Channel sendChannel = UserChannelRel.get(sendUserId);
        if(sendChannel != null) {
            DataContent dataContent = new DataContent();
            dataContent.setAction(MsgActionEnum.PULL_FRIEND.getType());
            sendChannel.writeAndFlush(new TextWebSocketFrame(JsonUtil.obj2String(dataContent)));
        }
        return ServerResponse.createBySuccess("添加好友成功");
    }

这是获得好友的方法B

    public ServerResponse<List<MyFriendVO>> queryMyFriends(Long userId) {
        Integer count = userRepository.countById(userId);
        if(count == 0) {
            return ServerResponse.createByError("该用户不存在");
        }
        return ServerResponse.createBySuccess(userRepository.queryMyFriends(userId));
    }

我们之前在添加通讯录好友的方法中因为是要双向添加好友并且删除申请记录的,三个数据库操作的service层我们带上了事务.
现在我遇到一个问题, 就是在这个事务方法中通过socket通知客户端去拉取最新的好友. 但每次socket一通知,客户端去服务端拉取数据,都没有获得最新的数据.试了好多次都是这样.

一分析下来只有可能是A方法事务还没有提交, 然后B方法直接去获取最新数据导致的
(这里还有个嵌套的小问题, 从socket通知客户端, 到客户端发起ajax请求到服务端怎么着都有个十几毫秒吧, 这么长的时间难道还不够A方法的事务提交吗 希望老师也能解答一下这个问题)

现在我有两个方法去解决这个问题,
一是客户端在收到socket通知后再延迟1s去执行

function fetchContactList() {
	setTimeout(() => {
		console.log("去请求了")
		var user = app.getUserGlobalInfo();
		
		console.log("这个是去获取好友的接口")
		console.log(app.serverUrl + "/client/user/myFriends?userId=" + user.id)
		
		mui.ajax(app.serverUrl + "/client/user/myFriends?userId=" + user.id,{
			data:{},
			dataType:'json',//服务器返回json格式数据
			type:'post',//HTTP请求类型
			timeout:100000,//超时时间设置为10秒;
			headers:{'Content-Type':'application/json'},	              
			success:function(data){
		
				console.log("这个是去请求的返回值", JSON.stringify(data))
				if (data.code == 0) {
					var contactList = data.data;
					app.setContactList(contactList);
				}
			}
		});
	}, 1000)
}

二是将B方法的事务隔离级别设置为可读未提交

@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public ServerResponse<List<MyFriendVO>> queryMyFriends(Long userId) {
    Integer count = userRepository.countById(userId);
    if(count == 0) {
        return ServerResponse.createByError("该用户不存在");
    }
    return ServerResponse.createBySuccess(userRepository.queryMyFriends(userId));
}

我自己试过了, 这两种方法都能达到效果, 但是都不够优雅.
所以请问老师视频中没有遇到跟我一样的问题呢, 还有怎样才能确保A事务提交之后, B事务再开始请求呢?

写回答

2回答

风间影月

2019-03-29

//img.mukewang.com/szimg/5c9d7b390001a6e215010721.jpg
加群参考下图

0
0

风间影月

2019-03-29

事务提交后,数据库查看有新的值吗?之前有个同学和你一模一样的问题,他是mybatis没有配置好的缘故,就是事务无法自动提交

0
7
风间影月
回复
学东西要快
进入课程目录,然后会有群号
2019-03-29
共7条回复

Netty+Spring Boot仿微信-全栈开发高性能后台及客户端

SpringBoot/Netty+MUI全栈开发 同时搞定后台+ Android&iOS

1498 学习 · 684 问题

查看课程