- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
[编辑] 这个问题是“如何使用 EJB 3 和 JPA 2.0 对实体 bean 进行原子更改”。应该很简单吧?
我尝试根据目前得到的答案修复我的代码。我正在使用 JBoss 6.0.0M2 和 Hypersonic(只需下载并调用 run.bat)。
我的测试用例:创建 3 个线程并在循环中调用其中一个 testCounterMitLock*()
500 次。所以一个成功的测试应该打印“Anzahl eingetragene Zeilen: 1500” (3*500)。
我试过:
CounterTestVersion ct = manager.find(CounterTestVersion.class, 1);
manager.lock(ct, LockModeType.WRITE);
int wert = ct.getWert();
显然是行不通的,因为不同的线程可以在应用锁之前更改数据库中的值。所以我尝试解决这个问题:
CounterTestVersion ct = manager.find(CounterTestVersion.class, 1);
manager.lock(ct, LockModeType.WRITE);
manager.refresh (ct);
int wert = ct.getWert();
refresh()
应该给我当前值并且隐式查询还应该确保对象现在被锁定。没有这样的运气。让我们尝试使用 JPA 2.0:
CounterTestVersion ct = manager.find(CounterTestVersion.class, 1, LockModeType.WRITE);
int wert = ct.getWert();
那也行不通。也许锁还不够?
CounterTestVersion ct = manager.find(CounterTestVersion.class, 1, LockModeType.PESSIMISTIC_WRITE);
int wert = ct.getWert();
嗯……也不行!最后一次绝望的尝试:
CounterTestVersion ct = manager.find(CounterTestVersion.class, 1, LockModeType.PESSIMISTIC_WRITE);
manager.flush();
manager.refresh (ct);
int wert = ct.getWert();
好的...谁能解释为什么什么都不起作用?我没主意了。
[EDIT2] PS:雪上加霜的是,这是最后一个运行线程的最后输出:
commit/rollback: 441/62
(441+62 = 503)...
这是完整的代码。首先是 bean :
package server.kap15;
import java.rmi.RemoteException;
import javax.ejb.*;
import javax.persistence.*;
@Stateful
public class CounterTestBean implements CounterTestRemote, SessionSynchronization {
@PersistenceContext(unitName = "JavaEE")
EntityManager manager;
private int commit = 0;
private int rollback = 0;
public void initDatenbank() {
manager.createNamedQuery("CounterTest.deleteAll").executeUpdate();
manager.createNamedQuery("TestTabelle.deleteAll").executeUpdate();
CounterTestVersion ct = new CounterTestVersion();
ct.setNr(1);
ct.setVersion(1);
ct.setWert(1);
manager.persist(ct);
}
public boolean testCounterOhneLock() {
try {
CounterTest ct = manager.find(CounterTest.class, 1);
int wert = ct.getWert();
ct.setWert(wert + 1);
TestTabelle tt = new TestTabelle();
tt.setNr(wert);
manager.persist(tt);
manager.flush();
return true;
} catch (Throwable t) {
return false;
}
}
public boolean testCounterMitLock() {
try {
CounterTestVersion ct = manager.find(CounterTestVersion.class, 1);
manager.lock(ct, LockModeType.WRITE);
int wert = ct.getWert();
ct.setWert(wert + 1);
TestTabelle tt = new TestTabelle();
tt.setNr(wert);
manager.persist(tt);
manager.flush();
return true;
} catch (Throwable t) {
return false;
}
}
public boolean testCounterMitLock2() {
try {
CounterTestVersion ct = manager.find(CounterTestVersion.class, 1);
manager.lock(ct, LockModeType.WRITE);
manager.refresh (ct);
int wert = ct.getWert();
ct.setWert(wert + 1);
TestTabelle tt = new TestTabelle();
tt.setNr(wert);
manager.persist(tt);
manager.flush();
return true;
} catch (Throwable t) {
return false;
}
}
public boolean testCounterMitLock3() {
try {
CounterTestVersion ct = manager.find(CounterTestVersion.class, 1, LockModeType.WRITE);
int wert = ct.getWert();
ct.setWert(wert + 1);
TestTabelle tt = new TestTabelle();
tt.setNr(wert);
manager.persist(tt);
manager.flush();
return true;
} catch (Throwable t) {
return false;
}
}
public boolean testCounterMitLock4() {
try {
CounterTestVersion ct = manager.find(CounterTestVersion.class, 1, LockModeType.PESSIMISTIC_WRITE);
int wert = ct.getWert();
ct.setWert(wert + 1);
TestTabelle tt = new TestTabelle();
tt.setNr(wert);
manager.persist(tt);
manager.flush();
return true;
} catch (Throwable t) {
return false;
}
}
public boolean testCounterMitLock5() {
try {
CounterTestVersion ct = manager.find(CounterTestVersion.class, 1, LockModeType.PESSIMISTIC_WRITE);
manager.flush();
manager.refresh (ct);
int wert = ct.getWert();
ct.setWert(wert + 1);
TestTabelle tt = new TestTabelle();
tt.setNr(wert);
manager.persist(tt);
manager.flush();
return true;
} catch (Throwable t) {
return false;
}
}
public boolean testCounterMitVersion() {
try {
CounterTestVersion ctv = manager.find(CounterTestVersion.class, 1);
int wert = ctv.getWert();
ctv.setWert(wert + 1);
manager.flush();
TestTabelle tt = new TestTabelle();
tt.setNr(wert);
manager.persist(tt);
manager.flush();
return true;
} catch (OptimisticLockException e) {
System.out.println(">>> Versionskonflikt !");
return false;
} catch (Throwable t) {
System.out.println(t.getMessage());
return false;
}
}
public long anzTestZeilen() {
Query query = manager.createNamedQuery("TestTabelle.anzZeilen");
Long anzahl = (Long) query.getSingleResult();
return anzahl;
}
public void afterBegin() throws EJBException, RemoteException {
}
public void beforeCompletion() throws EJBException, RemoteException {
}
public void afterCompletion(boolean committed) throws EJBException,
RemoteException {
if (committed)
commit++;
else
rollback++;
System.out.println("commit/rollback: " + commit + "/" + rollback);
}
}
远程接口(interface):
package server.kap15;
import javax.ejb.Remote;
@Remote
public interface CounterTestRemote {
public void initDatenbank();
public boolean testCounterOhneLock();
public boolean testCounterMitLock();
public boolean testCounterMitLock2();
public boolean testCounterMitLock3();
public boolean testCounterMitLock4();
public boolean testCounterMitLock5();
public boolean testCounterMitVersion();
public long anzTestZeilen();
}
persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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_1_0.xsd"
version="1.0">
<persistence-unit name="JavaEE">
<jta-data-source>java:DefaultDS</jta-data-source>
</persistence-unit>
</persistence>
测试客户端:
package client.kap15;
import java.util.Properties;
import javax.naming.*;
import javax.rmi.PortableRemoteObject;
import server.kap15.CounterTestRemote;
public class CounterTestMitLock extends Thread {
CounterTestRemote ctr;
public static void main(String[] args) {
try
{
testMitLock();
testMitLock2();
testMitLock3();
testMitLock4();
testMitLock5();
}
catch (Exception e)
{
e.printStackTrace ();
}
}
static int N = 3;
static CounterThread[] ct = new CounterThread[N];
private static void testMitLock () throws InterruptedException
{
System.out.println("--- Counter Test MIT Lock ----------------------");
System.out.println("Testinstanzen erzeugen...");
for (int i=0; i<N; i++)
ct[i] = new CounterThreadMitLock();
runTest ();
}
private static void testMitLock2 () throws InterruptedException
{
System.out.println("--- Counter Test MIT Lock2 ----------------------");
System.out.println("Testinstanzen erzeugen...");
for (int i=0; i<N; i++)
ct[i] = new CounterThreadMitLock2();
runTest ();
}
private static void testMitLock3 () throws InterruptedException
{
System.out.println("--- Counter Test MIT Lock3 ----------------------");
System.out.println("Testinstanzen erzeugen...");
for (int i=0; i<N; i++)
ct[i] = new CounterThreadMitLock3();
runTest ();
}
private static void testMitLock4 () throws InterruptedException
{
System.out.println("--- Counter Test MIT Lock4 ----------------------");
System.out.println("Testinstanzen erzeugen...");
for (int i=0; i<N; i++)
ct[i] = new CounterThreadMitLock4();
runTest ();
}
private static void testMitLock5 () throws InterruptedException
{
System.out.println("--- Counter Test MIT Lock5 ----------------------");
System.out.println("Testinstanzen erzeugen...");
for (int i=0; i<N; i++)
ct[i] = new CounterThreadMitLock5();
runTest ();
}
private static void runTest () throws InterruptedException
{
System.out.println("Datenbank initialisieren...");
ct[0].ctr.initDatenbank();
System.out.println("Test durchführen...");
for (int i=0; i<N; i++)
ct[i].start();
System.out.println("Auf Ende warten...");
for (int i=0; i<N; i++)
ct[i].join();
System.out.println("Anzahl eingetragene Zeilen: " + ct[0].ctr.anzTestZeilen());
}
private static CounterTestRemote verbinden() {
try {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
p.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
p.put(Context.PROVIDER_URL, "jnp://localhost:1099");
Context ctx = new InitialContext(p);
Object ref = ctx.lookup("CounterTestBean/remote");
CounterTestRemote ctr = (CounterTestRemote) PortableRemoteObject.narrow(ref, CounterTestRemote.class);
return ctr;
} catch (NamingException e) {
System.out.println("ERROR - NamingException!");
System.exit(-1);
}
return null;
}
public abstract static class CounterThread extends Thread
{
protected CounterTestRemote ctr;
public CounterThread ()
{
this.ctr = verbinden ();
}
public void run() {
for (int i = 0; i < 500; i++)
test ();
}
public abstract void test ();
}
public static class CounterThreadMitLock extends CounterThread
{
@Override
public void test ()
{
this.ctr.testCounterMitLock();
}
}
public static class CounterThreadMitLock2 extends CounterThread
{
@Override
public void test ()
{
this.ctr.testCounterMitLock2();
}
}
public static class CounterThreadMitLock3 extends CounterThread
{
@Override
public void test ()
{
this.ctr.testCounterMitLock3();
}
}
public static class CounterThreadMitLock4 extends CounterThread
{
@Override
public void test ()
{
this.ctr.testCounterMitLock4();
}
}
public static class CounterThreadMitLock5 extends CounterThread
{
@Override
public void test ()
{
this.ctr.testCounterMitLock5();
}
}
}
最佳答案
由于所有锁定模式都不起作用,我尝试了 ewernli使用手动 SELECT ... FOR UPDATE
的解决方案。这给出了一个有趣的异常(exception):“意外的 token FOR”。所以我查看了数据库。
JBoss 安装有 Hypersonic 1.8 (HSQLDB) 默认不支持行锁定。亲爱的 JBoss 开发人员:当不支持锁定模式时,JPA 实现应该抛出异常。
所以我添加了一个 Oracle 数据源并更改了我的 persistence.xml。之后,两个测试工作:
CounterTestVersion ct = manager.find(CounterTestVersion.class, 1, LockModeType.PESSIMISTIC_WRITE);
int wert = ct.getWert();
和
Query query = manager.createNativeQuery ("select * from COUNTER_TEST where NR = 1 for update", CounterTestVersion.class);
CounterTestVersion ct = (CounterTestVersion)query.getSingleResult ();
int wert = ct.getWert ()+1;
这很有趣。它也应该与 LockModeType.PESSIMISTIC_FORCE_INCREMENT
一起使用。在这种情况下,我在日志中看到了这个错误:
ORA-00054: resource busy and acquire with NOWAIT specified
这发生在调用 manager.find()
中。我不明白为什么两者在加载阶段表现不同。可能是 JBoss 或 Hibernate 中的错误。
关于java - 如何使用 EJB 3.0 实现适当的计数器 bean?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2551128/
有什么区别 和 您能解释一下这两者之间有什么区别吗? 最佳答案 它是一个 XML 命名空间,用于分隔可能存在冲突的元素名称,因此没有真正的区别。 XML Namespaces 关于java -
我刚刚浏览了两个 Web 应用程序,在两个项目的“applicationContext.xml”文件中都有一个标记 ... 另一个是 ... 谁能给我解释一下有什么区别吗? 最佳答案 没有语
我一直在尝试了解 WebSphere Commerce 中的 Java bean,但我真的很困惑。请帮帮我。我需要知道: What is the difference between EntityBe
自从我们更新到 grails 2.0.1(从 2.0.0 开始)以来,通过 bean 字段显示的所有 bean 都错误地显示为“withBean”字段的第一个属性。在我下面发布的示例中,所有 [fir
我有一个 bean,我将另一个 beanlist 放入其中,并且我想访问该内部 bean。 我的第一个 Bean 是: public class FirstDTO { private String F
我正在尝试将 CSS 和 JS 添加到 spring MVC 项目中的 JSP 页面,以便我在 dispatcher-servlet.xml 中包含了 js/css 文件夹的引用,如下所示:
当我将请求传递给 RestController 时,出现以下错误。 org.springframework.beans.factory.xml.XmlBeanDefinitionStoreExcept
我看到很多示例将 bean 标记为实体 bean (@Entity) 和命名 bean (CDI),以避免创建 2 个类(托管 bean 和实体 bean)并利用 Bean 验证以便可以执行验证在客户
在我的理解中, session 总是意味着有状态。考虑 servlet session 对象, 想想 cookie。如果 session 是无状态的,我认为我们根本不需要 session 。 在jee
我完全是Spring框架的初学者。我当时正在玩一个创建对象实例的示例。因此需要您的帮助! 看看这个例子: MainApp.java: import org.springframework.contex
这个问题在这里已经有了答案: What is a JavaBean exactly? (23 个回答) 关闭 7 年前。 我已经阅读了有关 EJB、Java Beans 的内容,但是我仍然对“bea
我刚开始使用 Spring-Framework,实际上我正在使用 spring-boot 库。我有以下问题: 我知道在 @Configuration 类中使用 @Bean 注册的 bean 默认是单例
我对下面提到的场景中使用Spring Framework时会创建的实例数量有疑问: bean配置是这样的 or 默认情况下,bean "a"有 singleton scope .所以
在我的 Spring-Module.xml 中,我有两个 bean: ... ... 我像这样实例化我的类: Applicat
@Autowired private Map departments; 我的 spring 配置文件 只要使用 @Autowired 需要日期,它就可以正常工作 同样, 如何使用没有属性
我已经为 ComboBox 设置了 ContainerDataSource this.comboBox.setContainerDataSource(container)。这个容器是一个 BeanIt
为了支持流畅的编程风格,我最近修改了我们的 Java Beans setter 方法以返回 Bean 类。但是现在 Java Beans Activation Framework (rel 1.1)
有人可以告诉我在我的 ApplicationContext 中我必须使用 beans:bean 而不是 bean 的什么以及如何修复它。
我有如下配置: batch:job id="reconciliationJob" job-repository="jobRepository" restartable="true" 在应用程序上下文启
我已经为 Test_flow 创建了简单的测试套件,但是当我尝试运行该流程时出现错误。 java.lang.RuntimeException: org.mule.api.config.Configur
我是一名优秀的程序员,十分优秀!