abcbuzhiming 2014-05-09 22:37 采纳率: 0%
浏览 500
已采纳

迷茫了,service层里到底该写啥,才比较符合j2ee的定义

spring+hibernate 或 spring+mybatis结构

以前写简单的crud,还没有感觉到问题。最近写游戏,逻辑复杂多了,比如有个功能,要求,用户登陆后,检测用户持有的道具纪录,如果发现有纪录没有的(因为游戏更新,会加新道具),要插入。我这么干的
@service
public class UserInfoServiceImpl implements UserInfoService
{
private GoodsInfoService goodsInfoService;
public GoodsInfoService getGoodsInfoService() {
return goodsInfoService;
}

@Resource
public void setGoodsInfoService(GoodsInfoService goodsInfoService) {
    this.goodsInfoService = goodsInfoService;
}

@Override
public boolean selectUserLogin(UserInfo userInfo)
{
List userGoodsInfos = goodsInfoService
.selectUserAllGoods(userId); // 获取玩家所有的道具
//伪代码,
//遍历检测是否有缺少的然后插入新的
userGoodsInfos = goodsInfoService
.selectUserAllGoods(userId); //再次获得新的玩家道具列表
。。。。。。。
}
}
坑爹的是,select用的事务传播级别为support,一般select不需要事务,但是hibernate和mybatis都存在session缓存,在selectUserLogin方法中selectUserAllGoods执行了两次,但是实际上只得到了同样的结果,第二次执行未查询数据库而是直接就从缓存中取得。而实际上结果集在数据库里已经编了,我对这个地方很纠结,不知道应该改造成什么样子,似乎service上面还需要再有一层来处理逻辑,但是service不处理逻辑,那就是纯粹的crud,把dao的工作抢去了。那像我这样检测旧纪录,插入新纪录,插入完后再次查询,并获得新结果集的service层到底该怎么写,如何设置事务传播级别?

  • 写回答

2条回答 默认 最新

  • hadeslbf 2014-05-11 23:34
    关注

    调整selectUserAllGoods方法的事务隔离级别,事务隔离级别分为如下几种:

    1. 读未提交,最低的级别,此级别可以读到其他事务未处交的数据,此级别性能最高,但是会有脏读的数据。

    2. 读已提交,此级别保证读到的数据都是其他事务已提交的数据,不会读到脏数据,但是不可重复读,也就是同样的条件下,第一次读到的数据和第二次读到的数据,可能是会变化的。

    3. 可重复读,此级别保证的是同样的条件下,第一次读到的数据和第二次读到的数据是不会变的,对应数据库的实现方式应该是就是锁行,锁定读到的那些数据行,但是此级别会有一个问题,那就是幻读,也就是说,同样的条件,第一次可能读到了10条数据,第二次可能读到了11条数据,因为多的那个数据是新插入的。

    4.序列化,最高隔离级别,对应的基本上就是锁表,安全性最高,但是性能最低,此级别可以保证不会出现幻读。

    根据你的需求,你的隔离级别应该设置为2.读已提交。mysql的默认级别是3.可重复读,所以你可能需要显式地设置你的事务隔离级别。

    如果你用的是spring,那么加如下注解就可以了:

    [code="java"]@Transactional(isolation = Isolation.READ_COMMITTED)[/code]

    如果你用的是JDBC的话,直接在Connection对象上设置隔离级别,如下:

    [code="java"]conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);[/code]

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • ll89308839 2014-05-11 23:17
    关注

    @Override
    public boolean selectUserLogin(UserInfo userInfo)
    {
    List userGoodsInfos = goodsInfoService
    .selectUserAllGoods(userId); // 获取玩家所有的道具
    //伪代码,
    //遍历检测是否有缺少的然后插入新的
    userGoodsInfos = goodsInfoService
    .selectUserAllGoods(userId); //再次获得新的玩家道具列表
    。。。。。。。
    }
    }

    其实这里的逻辑还是数据库的访问呗,所以你把dao层扩展就可以了,service还是直接用就行了

    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 activity升级到flowable工作流act_ge_bytearray的草稿json数据复制到act_de_model 的model_editor_json的脚本
  • ¥15 cvi使用CreateThread创建线程时,出现存储空间不足无法处理此命令的错误
  • ¥15 求苹果推信imessage批量推信技术
  • ¥15 ubuntu 22.04 系统盘空间不足。隐藏的docker空间占用?(相关搜索:移动硬盘|管理系统)
  • ¥15 利用加权最小二乘法求亚马逊各类商品的价格指标?怎么求?
  • ¥15 c++ word自动化,为什么可用接口是空的?
  • ¥15 Matlab计算100000*100000的矩阵运算问题:
  • ¥50 VB6.0如何识别粘连的不规则的数字图片验证码
  • ¥16 需要完整的这份订单所有的代码,可以加钱
  • ¥30 写一个带界面控制的机房电脑一键开机关机并且实时监控的软件