Java 如何防止客户端应用程序中重复出现EntityManager事务代码(打开、提交、关闭)?
有没有更好的方法来编写数据库方法,而不必总是获取实体管理员、开始事务、提交、关闭等Java 如何防止客户端应用程序中重复出现EntityManager事务代码(打开、提交、关闭)?,java,database,hibernate,postgresql,Java,Database,Hibernate,Postgresql,有没有更好的方法来编写数据库方法,而不必总是获取实体管理员、开始事务、提交、关闭等 private updateDB() { EntityManager em = EntityManagerFactory.get(); em.getTransaction().begin(); //do some DB stuff em.getTransaction().commit(); em.close();
private updateDB() {
EntityManager em = EntityManagerFactory.get();
em.getTransaction().begin();
//do some DB stuff
em.getTransaction().commit();
em.close();
}
它必须在没有任何应用服务器的情况下工作,只有一个本地客户端JavaSE应用程序。您可以使用一个和一个接口回调来实现模板方法
这种模板方法模式的一个简短示例如下所示:
public class TransactionTemplate {
public <T> T execute(Callable<T> doInTransaction) throws Exception {
EntityManager em = EntityManagerFactory.get();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
try {
T result = doInTransaction.call();
transaction.commit();
return result;
} catch(/* Some exception that causes a rollback */ e) {
transaction.rollback();
throw e;
} finally {
em.close();
}
}
}
公共类事务模板{
public T execute(可调用的doInTransaction)引发异常{
EntityManager em=EntityManager工厂.get();
EntityTransaction=em.getTransaction();
transaction.begin();
试一试{
T result=doInTransaction.call();
commit();
返回结果;
}catch(/*导致回滚的某个异常*/e){
transaction.rollback();
投掷e;
}最后{
em.close();
}
}
}
在代码中,您可以这样使用它
private updateDB() {
TransactionTemplate transaction = ... // get it somehow;
transaction.execute(new Callable<Void>(){
// will be executed in a transaction
public Void call() throws Exception {
//do some DB stuff
}
});
}
private updateDB(){
TransactionTemplate transaction=…//以某种方式获取它;
transaction.execute(newcallable()){
//将在事务中执行
public Void call()引发异常{
//做一些数据库的事情
}
});
}
注意:这与spring的事务模板使用的模式完全相同。所以,如果你能使用spring,你将免费获得它
根据用户311525评论进行编辑
没有传递对它的引用。例如,如果操作是persist(),它将如何执行。。。我猜有必要使用ThreadLocal`
有几种方法可以使实体管理器
引用可用于可调用
使用注释中建议的用户311525的ThreadLocal
不要使用标准的Callable
引入自己的接口,例如EMAwareCallable.call(EntityManager)
如果可调用的
是匿名类,则通过封闭类的最后一个变量提供它
创建一个实现Callable
的类,并添加一个构造函数来传递对它的引用
每种方法在实现工作、可测试性、可扩展性(标准java接口与否)等方面都有其优缺点。这取决于您的选择。我认为最好将您的数据置于事务的保护之下,这样可以使您的数据具有集成和回滚安全性!所以你只想玩DB,玩得开心!我可以在不在任何服务器上运行的客户端应用程序中使用Spring吗?如果是,那么春天可能是我的选择?=@membersound是的,你可以。看看@membersound,你也可以像普通类一样使用很多spring类,而不需要启动应用程序上下文。因此,我也可以用@Transactional
注释我的DB方法。我可以吗?@membersound是的,你可以使用@Transactional
。因为spring默认使用java代理,所以必须创建db类实现的接口。然后可以在spring上下文xml中定义db impl,并启用基于spring注释的事务管理。然后,如果您从应用程序上下文请求db access对象,Spring将创建一个事务感知代理。