我有一个客户端服务器应用程序,并且在我的服务器中,我正在使用hibernate模式进行数据库处理。现在,我的应用程序需要所有数据库表中的一个简单表,其中仅一个行包含一个Biginteger
字段(这是该行的键)。该表实际上仅包含一个全局编号(从1开始),我在用户每次执行某些操作时都会使用该编号,当他执行此操作时,我需要获取该值并在数据库中递增该值。(表应该只包含一行,并且始终只有一个值)
我正在使用以下代码来完成该任务:
Biginteger func() {
Session s = null;
Biginteger idToReturn=null;
try{
s=factory.openSession();
s.beginTransaction();
Query queryResult = s.createQuery("from GlobalId");
List<GlobalID> theId=queryResult.list();
idToReturn=theId.get(0).get_id(); //getting the value from db to return
GlobalID toSave=new GlobalId();
toSave.set_id(idToReturn.add(BigInteger.valueOf(1))); //incrementing the id from db inorder to save it
s.delete(theId.get(0)); //deleting old id
s.save(toSave); //saving new id
s.getTransaction().commit();
}
catch(Exception e){
throw e;
}
finally{
if (s!=null)
s.close();
return idToReturn;
}
}
此代码可以正常工作。我担心的是,是否需要使用多台服务器来访问中央数据库。在这种情况下,如果两个单独的服务器将运行此功能,则我需要消除两个服务器将获得相同值的情况。我需要确保整个读取和写入都是“原子的”,我需要锁定该表,以便不超过一个会话能够读取该值,并且我还需要确保万一会话意外结束,锁将被移除。
我正在使用包括MySQL 5.6数据库的xampp软件包。
我在网上找到的有关此问题的信息使我感到困惑-我发现的信息是“高级”的,我找不到任何示例。
您需要使用悲观锁定,这可以通过
setLockMode(String alias, LockMode lockMode)
关于查询和使用LockMode.UPGRADE
。
请参阅Query.setLockMode
但是,如果您对此表进行大量访问,那么这肯定会破坏可伸缩性和性能。您最好使用序列或另一种策略来创建一个分配数字的服务(例如,SSB),该服务一次可以获取100个数字,更新数据库并将其分发出去。这样可以节省198次数据库访问。
更新:
您还必须稍微修改表格设计。最好有一个具有已知ID的单行,然后将要递增的数字存储在另一列中。然后,您应该更新该行,而不是删除旧行并添加新行。否则,行锁定策略将不起作用。
UPDATE2:
OP发现以下工作有效:
session.get(class.Class, id, lockOption)
问题内容: 如果我有如下代码: 在开始和提交之间,正在读取的表是否被锁定,并且随后是否会在多用户环境中引起问题,在该环境中,当另一个用户调用上面的相同代码时会发生问题? 如果以上情况有问题,我们是否应始终尝试缩短交易时间?并为此提供便利,而不是在懒惰的关系上调用getter方法,这是否意味着最好使交易简短并为父母的子女手动查找? 问题答案: Hibernate不会做任何事情来显式锁定您从中读取的表
问题内容: 我正在使用Hibernate,试图模拟2个并发更新到数据库中的同一行。 编辑:我将em1.getTransaction()。commit移到em1.flush()之后;我没有收到任何StaleObjectException,两个事务已成功提交。 我在上遇到以下异常。为什么? 问题答案: 好吧,您正试图陷入僵局,并且成功了:-) Transaction1开始,与您的实体更新(和锁定)行。
问题内容: 我有这样的方法: 我期望通过使用REQUIRES_NEW事务传播和所示的递归,StaleObjectStateException最终将被清除,但事实并非如此。 如何从此异常中恢复? 问题答案: 原来有一个我忽略了的“ gatcha” … 从Spring文档 在代理模式(默认)下,将仅拦截通过代理传入的“外部”方法调用。这意味着即使调用的方法标记有@Transactional,“自调用”
问题内容: 我在项目中使用了hibernate模式,并且由于非常简单的数据库操作而获得了随机的表观死锁。 有一个堆栈跟踪:https : //gist.github.com/knyttl/8999006 –让我感到困惑的是,第一个异常是RollbackException,然后是LockAquisition异常。 问题经常发生在类似的条款上: 我很困惑,因为我不知道这是Hibernate,MySQL
问题内容: 我有一个Spring和Hibernate3在生产中运行良好的应用程序。以下是Spring的applicationContext.xml中会话工厂的配置 生产正常。 现在,对于另一个项目,我们正在迁移到Hibernate4。我们使用org.springframework.orm.hibernate4。*包中的Hibernate 4的SessionFactory,TransacionMan
问题内容: 我正在寻找展示如何将MongoDB与Hibernate集成的资源(最好是在Spring内),以便我可以在RDBMS和NoSql替代品之间进行切换:有人有这样做的经验吗? 问题答案: 您不能轻易做到这一点。Hibernate的重点是将Java对象映射到关系数据库。尽管Hibernate提取了许多细节,但您仍然需要了解关系数据库如何与诸如外键和主键之类的东西一起工作,以及运行查询对性能的影