【问题标题】:JPA transaction commit strange behaviourJPA 事务提交奇怪的行为
【发布时间】:2014-03-14 22:14:30
【问题描述】:

我正在尝试了解 jpa 事务工作。

假设我有以下persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="survex" transaction-type="JTA">
    <jta-data-source>jdbc/MyDatabase</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
    </properties>
  </persistence-unit>
</persistence>

以及以下带有嗅探mysql服务器的测试代码:

public class Servlet extends HttpServlet {

    @PersistenceContext(type = PersistenceContextType.TRANSACTION)
    EntityManager em;

    @Resource
    UserTransaction utx;

    Log log;

    public void initialize() {
        log = em.find(Log.class, 1);
    }

    public void meth1() throws SystemException, NotSupportedException, HeuristicRollbackException, HeuristicMixedException, RollbackException {
        utx.begin();
        em.merge(log);
        log.setMessage(String.valueOf(Math.random()));
        utx.commit();
    }

    public void meth2() throws SystemException, NotSupportedException, HeuristicRollbackException, HeuristicMixedException, RollbackException {
        utx.begin();
        em.merge(log);
        log.setMessage(String.valueOf(Math.random()));
        utx.commit();
    }

    protected void doGet(HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {

        try {

            this.initialize();
            this.meth1(); // NOTHING HAPPENS!
            this.meth2(); 
            // SET autocommit=0; 
            // UPDATE LOG SET message = '0.1523804781755964' WHERE (id = 1);
            // commit;
            // SET autocommit=1;

        } catch ... {
            ...
        }
        response.getWriter().write("test");
    }
}

为什么?!为什么method1调用没有提交?

【问题讨论】:

  • 尝试移动 log.setMessage(String.valueOf(Math.random()));在 em.merge() 之前
  • 因为你得到一个例外?为什么您认为需要调用 merge(),尤其是在进行任何更改之前?
  • 谢谢!我期待实体经理的另一种行为。我认为在 transaction.commit() 之前,em 一直在跟踪合并的实体。并且仅在提交时检查实体是否“脏”。

标签: java jpa persistent-storage


【解决方案1】:

错误是一个典型的错误:调用merge()后,传递的日志没有得到管理。仅管理返回的实例。 请尝试以下操作:

public void meth1() throws SystemException, NotSupportedException, HeuristicRollbackException, HeuristicMixedException, RollbackException {
        utx.begin();
        Log newLog = em.merge(log);
        newLog.setMessage(String.valueOf(Math.random()));//we make the changes to the managed instance
        utx.commit();
    }

【讨论】:

  • Спасибо) 但我认为我帖子下的第二条评论是正确的,似乎 em 只合并了“脏”实体。
  • 我改了答案;)
  • 你是我的 JPA-MASTER!))
  • 我很高兴你想学习并且你听从了我对这些文章的建议;)
猜你喜欢
  • 1970-01-01
  • 2011-02-24
  • 2011-03-13
  • 1970-01-01
  • 1970-01-01
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多