两进程修改数据库,不同步有关问题的解决方法
两进程修改数据库,不同步问题的解决办法
应该是缓存的问题,hibernate缓存了数据库连接
的确,观察者模式。不过我有疑问,如果使用观察者模式,应该怎么样去实现
自己没有试过,对这个很感兴趣。
不过我想如果自己写个类似于通知的东西应该更加简单,简洁一些。
oracle才能这么玩吧。
无非以性能为代价呗。
一个进程不断查询数据库,看某个字段时候已经被修改,如果修改则做下一步工作;如果没有修改继续循环查询
另外一个进程由用户操作去更新数据库中的这个字段
问题是,在上面这样的场景中,查询数据库的进程根本看不到数据被修改
解决办法:
给第一个查询部分也加上事务管理的代码(一般情况下,对于修改,更新部分的代码才进行事务的管理,而这种查询代码都是直接查询的)
TasksDAO dao = new TasksDAO(); Transaction tran = dao.getSession().beginTransaction(); Tasks task = dao.findById(id); tran.commit(); dao.getSession().close();
1 楼
aaron7524
2009-06-30
?为什么会查不到呢
2 楼
kungstriving
2009-06-30
aaron7524 写道
?为什么会查不到呢
应该是缓存的问题,hibernate缓存了数据库连接
3 楼
香克斯
2009-06-30
通过ID的查询应该是一级缓存给缓存了,你也可以先evict(Object object)从缓存中驱逐指定的对象,之后再查询试试看
4 楼
魔力猫咪
2009-06-30
注意,如果使用了Hibernate之类的ORM并且使用了二级缓存,那么一定要保证所有的修改均通过该ORM进行。而且还要注意修改对缓存的影响,是否造成了脏数据。
其次,确认数据库的隔离级别,确保脏读、幻读、不可重复读等问题不至于影响数据安全。
如果你是两个完全单独的程序交互操作数据库,那么不要使用二级缓存。
其次,确认数据库的隔离级别,确保脏读、幻读、不可重复读等问题不至于影响数据安全。
如果你是两个完全单独的程序交互操作数据库,那么不要使用二级缓存。
5 楼
casheen
2009-06-30
为什么不用观察者模式来实现你的功能?
6 楼
casheen
2009-06-30
或者用aop,拦截你做修改操作的接口
7 楼
jianfeihit
2009-06-30
我觉得可以试试数据库的触发器
8 楼
treblesoftware
2009-06-30
casheen 写道
为什么不用观察者模式来实现你的功能?
的确,观察者模式。不过我有疑问,如果使用观察者模式,应该怎么样去实现
9 楼
whaosoft
2009-06-30
你的 修改 是
Tasks task = dao.findById(id);
task.setXX(XX) 吗? 要是这样的话 应该不会有问题吧
Tasks task = dao.findById(id);
task.setXX(XX) 吗? 要是这样的话 应该不会有问题吧
10 楼
ray_linn
2009-07-01
只能说这个设计太搓了,明知道有别的进程还需要修改数据库,还会用上hibernate。
11 楼
holan
2009-07-01
没搞明白,session是一级缓存,你每次查询如果重新建个session,再查询,会出现你说的情况吗?
如果不显示打开事务,每一次执行sql语句应该都是自动启动一个事务啊
如果不显示打开事务,每一次执行sql语句应该都是自动启动一个事务啊
12 楼
dengtl
2009-07-01
触发器 -> Java -> Send Message(JMS) -> MBean or Message Process Center
13 楼
ray_linn
2009-07-01
dengtl 写道
触发器 -> Java -> Send Message(JMS) -> MBean or Message Process Center
oracle才能这么玩吧。
14 楼
wangzy
2009-07-01
这么累阿,用hibernate乐观锁
15 楼
longtinghappy
2009-07-01
为什么不用个标签,只要查标签就可以知道数据库里改动没有,用在数据库里做这么多的查询
16 楼
kungstriving
2009-07-01
具体问题的原因我也没有去深入研究,但是采用给查询也加上事务的方法确实可以解决我的问题,呵呵
我有点急功近利了
我有点急功近利了
17 楼
rain2005
2009-07-01
你犯下最致命的错误的你根本不了解hibernate的工作方式,很明显在一个线程里面使用session总是命中一级缓存,
你修改后的代码能够成功的关键在这里
与事务无关,就算启用事务,对象还是在session缓存里面。
解决方式很多,比如清一级缓存,你选择了最差的一种方式。
再多说一句,查询怎么都不加事务?这毛病得改改。
你修改后的代码能够成功的关键在这里
dao.getSession().close();
与事务无关,就算启用事务,对象还是在session缓存里面。
解决方式很多,比如清一级缓存,你选择了最差的一种方式。
再多说一句,查询怎么都不加事务?这毛病得改改。
18 楼
rain2005
2009-07-01
ray_linn 写道
只能说这个设计太搓了,明知道有别的进程还需要修改数据库,还会用上hibernate。
为什么有别的进程还需要修改数据库就不能用hibernate,只要不启用二级缓存就OK。
19 楼
ray_linn
2009-07-01
rain2005 写道
ray_linn 写道
只能说这个设计太搓了,明知道有别的进程还需要修改数据库,还会用上hibernate。
为什么有别的进程还需要修改数据库就不能用hibernate,只要不启用二级缓存就OK。无非以性能为代价呗。
20 楼
faylai
2009-07-01
这样的设计就有问题,本身轮询数据库就不是件好事。