草庐IT

java - Hibernate 是否会在死锁时自动重启事务?

coder 2023-10-03 原文

关于这个话题已经有很多文章了:

我发现最后接受的答案特别有趣:

If you are using InnoDB or any row-level transactional RDBMS, then it is possible that any write transaction can cause a deadlock, even in perfectly normal situations. Larger tables, larger writes, and long transaction blocks will often increase the likelihood of deadlocks occurring. In your situation, it's probably a combination of these.

这意味着我们永远无法阻止它们,只能对付它们。真的吗?我想知道您是否可以在有 1000 人在线调用写数据库操作的网站上防止死锁。

谷歌搜索该主题没有得到任何有趣的结果。我找到的唯一一个是这个 ( http://www.coderanch.com/t/415119/ORM/databases/Deadlock-problems-Hibernate-Spring-MS ):

public class RestartTransactionAdviser implements MethodInterceptor {
    private static Logger log = Logger.getLogger(RestartTransactionAdviser.class);

    public Object invoke(MethodInvocation invocation) throws Throwable {
        return restart(invocation, 1);
    }

    private Object restart(MethodInvocation invocation, int attempt) throws Throwable {
        Object rval = null;
        try {
            rval = invocation.proceed();
        } catch (Exception e) {
            Throwable thr = ExceptionUtils.getRootCause(e);
            if (thr == null) {
                throw e;
            }

            if (StringUtils.contains(thr.getMessage(), "deadlock") || StringUtils.contains(thr.getMessage(), "try restarting transaction") || StringUtils.contains(thr.getMessage(),
                    "failed to resume the transaction")) {
                if (attempt > 300) {
                    throw e;
                }
                int timeout = RandomUtils.nextInt(2000);
                log.warn("Transaction rolled back. Restarting transaction.");
                log.debug("Spleep for " + timeout);
                log.debug("Restarting transaction: invocation=[" + invocation + "], attempt=[" + attempt + "]");
                Thread.sleep(timeout);
                attempt++;
                return restart(invocation, attempt);
            } else {
                throw e;
            }
        }
        return rval;
    }
}

另一方面,我严重怀疑这种解决方案的质量。您能否详细说明并解释什么是最好的死锁处理方式?如何处理银行和企业应用中的死锁?

最佳答案

Hibernate session 需要一个 transaction write-behind一级缓存。这使您能够将更改推迟到最后负责的时刻,从而减少锁定获取间隔(甚至发生在 READ_COMMITTED isolation level 中)。

这意味着您必须尽量减少所有交易时间,我可以推荐使用 FlexyPool为了这样的努力。您需要确保所有事务都尽可能短,以减少锁定间隔,从而提高可伸缩性。

锁定引入串行操作,根据Amdahl's law ,可扩展性与总串行操作分数成反比。

我的建议是首先着手减少交易间隔。索引将减少查询时间。 ORM 可能会生成糟糕的查询,因此请确保您的 integration tests verify expected queries against actual executed ones .

类似p6spy 的工具非常方便地为您的查询计时,因此请确保您也使用它。

当所有事务都尽可能短并且您仍然需要更多并发时,您可以转向水平可扩展性。您可以首先从同步主从复制策略开始,将读取重定向到节点从属节点,同时保留主节点进行写入事务。

关于java - Hibernate 是否会在死锁时自动重启事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26424184/

有关java - Hibernate 是否会在死锁时自动重启事务?的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  3. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  4. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  5. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  6. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  7. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  8. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  9. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  10. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

随机推荐