【问题标题】:How should manage Database transactions using Entity Manager in a relatively large application?在一个相对较大的应用程序中应该如何使用实体管理器来管理数据库事务?
【发布时间】:2011-11-11 21:26:00
【问题描述】:

我使用 MYSQL 数据库和 Swing 应用程序框架和 javax.persistence 开发了一个相当大的 CRUD 应用程序。 我的问题是我应该如何最好地管理我的事务给定 javax.persistence.Entitymanager? 目前,我有一个由 Application 类持有的实体管理器实例。它被传递给所有请求页面,这些页面又使用它来持久化和合并实体。我在应用程序启动时启动事务,并在每次进行更改时提交(并重新启动)。 它是否正确?或者我应该为每个组件/页面持有一个单独的实体管理器? 我应该什么时候承诺? 现在出现了所有这些问题,因为我最近开始遇到以下类型的异常: java.sql.SQLException:超过锁定等待超时;尝试重新启动事务错误代码:1205 这让我相信我在管理数据库事务时做错了什么......

提前感谢您能给我的任何帮助!

【问题讨论】:

    标签: java mysql persistence entitymanager swing-app-framework


    【解决方案1】:

    在应用程序启动时启动事务并不是最好的主意。事务应该尽可能短,因为每个事务都会锁定数据库。我的意思是,每次启动事务时,没有其他线程可以写入数据库。你做事的方式恰恰相反:你的数据库不仅仅在很短的时间内被锁定。这可能是您遇到错误的原因。

    一般来说,推荐的事务管理方式如下:

    EntityManager em = EMF.getEM();
        em.getTransaction().begin();
        // your persist, merge code goes here
        em.getTransaction().commit();
        em.close();
    

    EMF 类是这个:

    public class EMF {
        private static EntityManagerFactory emf;
        static {
            emf = Persistence.createEntityManagerFactory("MyEMF");
        }
        public static EntityManager getEM(){
            return emf.createEntityManager();
        }
    }
    

    这样,您的事务仅在执行持久性代码期间锁定数据库。请注意,使用 EMF 类,您的实体管理器工厂只创建一次。这很好,因为创建它的计算成本很高。但是,一旦创建了实体管理器的实例,就非常便宜。这个short tutorial 解释得很好。

    【讨论】:

    • 非常感谢!最后有人向我解释了这一点......不过有一个问题:为什么在你的例子中让电动势静态?可以让它成为 EMF 的私人成员吗?在我的例子中,emf 的构建稍微复杂一些,所以我更喜欢在我的应用程序类的 init 函数中进行。我在想以下几点: public class EMF { private EntityManagerFactory emf;静态 { emf = Persistence.createEntityManagerFactory("MyEMF"); } 公共静态 EntityManager getEM(){ return emf.createEntityManager(); } }
    • 好吧,将 emf 设为静态的主要原因是 getEM 方法也是静态的,并且无法从静态上下文中引用非静态字段。由于我不打算实例化 EMF 类,因此将方法 getEM 设为静态会更有意义。如果您不想将 emf 设为静态字段,则还需要将 getEM 设为非静态。
    猜你喜欢
    • 2018-07-11
    • 2019-05-21
    • 2012-11-24
    • 2019-06-12
    • 1970-01-01
    • 2012-06-28
    • 2015-04-22
    • 2014-11-01
    • 1970-01-01
    相关资源
    最近更新 更多