gpt4 book ai didi

multithreading - Hibernate的线程问题

转载 作者:行者123 更新时间:2023-12-04 17:55:25 24 4
gpt4 key购买 nike

我在Hibernate中遇到一种奇怪的行为。我已经将头撞墙了一段时间了,并将奖励所有导致+100赏金的解决方案的答案。

我有一个JAX-RS(Jersey)REST服务器,带有一个过滤器,该过滤器将每个请求关联一个Hibernate session 。

在一个请求中,客户端使用一个 session (和一个事务)发布一些存储在数据库中的数据。在随后的调用中,客户端尝试获取该实体,但是Hibernate找不到它。

一些观察:

  • 如果我同时运行多个客户端,则只能重现此内容。我从未设法通过一次运行一个客户端来重现它。)
  • 可以看到数据库中的实体ID,如果我重新启动服务器,则Hibernate会按原样找到该实体。
  • 如果我使用大小为1的线程池(无论我同时运行多少个客户端),都不会发生该错误。

  • 这是代码,并带有一些日志记录:
    chargeables.setId(new SecureRandom().nextLong());

    System.out.printf("%s, session: %s [%s]%n",
    Thread.currentThread(),
    System.identityHashCode(session),
    "session.beginTransaction()");

    session.beginTransaction();


    System.out.printf("%s, session: %s [%s]%n",
    Thread.currentThread(),
    System.identityHashCode(session),
    "session.save(id = "+chargeables.getId()+")");

    session.save(chargeables);


    System.out.printf("%s, session: %s [%s]%n",
    Thread.currentThread(),
    System.identityHashCode(session),
    "session.getTransaction().commit()");

    session.getTransaction().commit();

    获取实体的代码:
    System.out.printf("%s,  session: %s  [%s]%n",
    Thread.currentThread(),
    System.identityHashCode(session),
    "session.get("+id+")");

    Chargeables entity = (Chargeables) session.get(Chargeables.class, id);

    if (entity == null)
    System.out.printf("%s, session: %s [%s]%n",
    Thread.currentThread(),
    System.identityHashCode(session),
    "ENTITY NOT FOUND!");

    现在,这里是结果日志的摘录(带有一些其他打开/关闭 session 输出):
    Thread[Grizzly(5),5,main],  session:  2041842357  [factory.openSession()]
    Thread[Grizzly(5),5,main], session: 2041842357 [session.beginTransaction()]
    Thread[Grizzly(5),5,main], session: 2041842357 [session.save(id = 7939229356942262438)]
    Thread[Grizzly(5),5,main], session: 2041842357 [session.getTransaction().commit()]
    Thread[Grizzly(5),5,main], session: 2041842357 [session.close()]
    [...]
    Thread[Grizzly(7),5,main], session: 1717445911 [factory.openSession()]
    Thread[Grizzly(7),5,main], session: 1717445911 [session.get(7939229356942262438)]
    Thread[Grizzly(7),5,main], session: 1717445911 [ENTITY NOT FOUND!]
    Thread[Grizzly(7),5,main], session: 1717445911 [session.close()]

    为什么在地球上我到达 ENTITY NOT FOUND!

    hibernate 版本:4.1.9.Final
    MySQL版本:14.14发行版5.5.29
    Chargeables的映射文件:
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

    <hibernate-mapping
    default-cascade="all"
    package="se.package.common.chargeables"
    default-lazy="false">


    <class name="Chargeables">

    <id name="id" type="long">
    <generator class="assigned"/>
    </id>

    <property name="startTimeStamp" />
    <property name="endTimeStamp" />

    <list name="chargeables">
    <key column="chargeableId" />
    <list-index column="pos" />
    <many-to-many class="Chargeable"/>
    </list>

    </class>


    <class name="Chargeable">

    <id column="id" type="long">
    <generator class="native"/>
    </id>

    <discriminator />

    <property name="timestamp" />

    </class>


    <subclass name="DataTransfer" extends="Chargeable">
    <property name="bytesSent" />
    <property name="bytesReceived" />
    </subclass>


    <subclass name="TelephonyChargeable" extends="Chargeable">
    <many-to-one name="num" />
    </subclass>

    <subclass name="Call" extends="TelephonyChargeable">
    <property name="duration" />
    </subclass>

    <subclass name="OutgoingCall" extends="Call" />
    <subclass name="IncomingCall" extends="Call" />

    <subclass name="Message" extends="TelephonyChargeable" />

    <subclass name="Sms" extends="Message" />
    <subclass name="IncomingSms" extends="Sms" />
    <subclass name="OutgoingSms" extends="Sms" />

    <subclass name="Mms" extends="Message" />
    <subclass name="IncomingMms" extends="Mms" />
    <subclass name="OutgoingMms" extends="Mms" />


    </hibernate-mapping>

    最佳答案

    恕我直言,这是一个隔离问题。您的第二个 session 在提交第一个 session 之前开始。由于默认的 hibernate 隔离级别为read_commited,因此第二个 session 无法如此检索实体。您如何在2个线程之间传递id?

    关于multithreading - Hibernate的线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15806893/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com