Transactions, how?

已查看 250 次
跳至第一个未读帖子

Jani Laakso

未读,
2010年9月17日 11:26:352010/9/17
收件人 OrientDB
First of all, I'd like to say I'm very happy to found a product such
as OrientDB.

I work for Vaadin Ltd and would like to create simple technology study
on how to use OrientDB with RIA (Vaadin). I got further plans also but
those depend on how mature OrientDB proves out, I understand that it's
bleeding edge technology currently.

Now, I got stuck with simple case on how to store two related POJOs in
a transaction.

// Database is created from scratch
// ...

// Store without transaction goes OK
Company company = new Company();
company.setName("Vaadin Ltd ");
Person person = new Person();
person.setName("Jani Laakso");
person.setCompany(company);
db.save(person);

// At this point I got 1 person and 1 company on the database

// Store with transaction NOT OK
Company company2 = new Company();
company2.setName("Vaadin Ltd ");
Person person2 = new Person();
person2.setName("Jani Laakso");
ODatabaseObjectTx tx = db.begin();
person2.setCompany(company2);
db.save(person2);
tx.commit();

// At this point I got 2 person and 1 (!) company on the database

Why do above code work differently? And if I comment the first case
(without TX) away, I get concurrent modification exception. However
when all above code is enabled no exception occurs.

Another transaction related question is that previously your API had
ODatabaseObjectTx being returned from db.begin(). Now it's returning
ODatabaseComplex<Object> based on latest source.

Can you please clarify how to use transactions with latest OrientDB.

Luca Garulli

未读,
2010年9月17日 11:43:072010/9/17
收件人 orient-database
Hi Jani,

On 17 September 2010 17:26, Jani Laakso <jani....@gmail.com> wrote:
First of all, I'd like to say I'm very happy to found a product such
as OrientDB.

I work for Vaadin Ltd and would like to create simple technology study
on how to use OrientDB with RIA (Vaadin). I got further plans also but
those depend on how mature OrientDB proves out, I understand that it's
bleeding edge technology currently.

Very interesting
I need to replicate your test case, can you attach your java file to a new issue? I need to know what version are you using and if you're working with "remote" or "local" database.

However you're using the ODatabaseObjectTx class that has a level more of abstraction than the ODatabaseDocumentTx. The problem could reside in it.

Another transaction related question is that previously your API had
ODatabaseObjectTx being returned from db.begin(). Now it's returning
ODatabaseComplex<Object> based on latest source.

Yes, the reason is the recent creation of the GraphDB interface that share a lot of logic from ODatabaseObjectTx, so it has been created the new base class DatabasePojoAbstract and it returns the generic type.

However you can write also:

db.begin();
person2.setCompany(company2);
db.save(person2);
db.commit(); // <-- USE THE DB INSTANCE AND NOT THE RETURNED VALUE OF DB.BEGIN(): IT'S THE SAME

 
Can you please clarify how to use transactions with latest OrientDB.

bye,
Lvc@

Jani Laakso

未读,
2010年9月17日 12:21:022010/9/17
收件人 OrientDB
Here you go..


package com.janilaakso;

import com.janilaakso.domain.Person;
import com.janilaakso.domain.Company;
import com.orientechnologies.orient.core.db.object.ODatabaseObjectTx;

public class TestMain {

public static String dbUrl = "local:/tmp/orient-database-test/foo";

private ODatabaseObjectTx db = null;

public static void main(String[] args) {
new TestMain().startup();
}

public void startup() {
db = new ODatabaseObjectTx(dbUrl);
if (db.exists()) {
db.open("admin", "admin");
} else {
System.out.println("Creating new database");
db.create();
}


db.getEntityManager().registerEntityClasses("com.janilaakso.domain");

try {
showElements("Before");

// Store without transaction goes OK
Company company = new Company();
company.setName("Vaadin Ltd ");
Person person = new Person();
person.setFirstname("Jani Laakso");
person.setCompany(company);
db.save(person);
// At this point I got 1 person and 1 company on the database
showElements("Without save");

// Store with transaction NOT OK
Company company2 = new Company();
company2.setName("Vaadin Ltd ");
Person person2 = new Person();
person2.setFirstname("Jani Laakso");
db.begin();
person2.setCompany(company2);
db.save(person2);
db.commit();
// At this point I got 2 person and 1 (!) company on the database
showElements("After save with TX");
} finally {
db.close();
}

}

private void showElements(String desc) {
System.out.println(desc + "--- " + Thread.currentThread());
for (String name : db.getClusterNames()) {
System.out
.println(name + " count=" + db.countClusterElements(name));
}
}
}



package com.janilaakso.domain;


public class Company {

private String name = null;
private String address = null;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setAddress(String address) {
this.address = address;
}

public String getAddress() {
return address;
}

@Override
public String toString() {
return super.toString() + ": name=" + name;
}
}




package com.janilaakso.domain;

public class Person {
private String firstname;
private String lastname;
private Company company;

public String getFirstname() {
return firstname;
}

public void setFirstname(String firstname) {
this.firstname = firstname;
}

public String getLastname() {
return lastname;
}

public void setLastname(String lastname) {
this.lastname = lastname;
}

public void setCompany(Company company) {
this.company = company;
}

public Company getCompany() {
return company;
}

@Override
public String toString() {
return super.toString() + ": firstname=" + firstname + ", lastname="
+ lastname + ", company=" + company;
}

}

Jani Laakso

未读,
2010年9月17日 12:23:182010/9/17
收件人 OrientDB
Just tested this with another version, above result came out from
trunk @ 1413.

BR Jani

Jani Laakso

未读,
2010年9月17日 12:22:252010/9/17
收件人 OrientDB
Above code should (to my understanding) create 2 person and 2 company
into db. Instead it creates 2 person and 1 (!) company.

Here's my system.out..


Creating new database
Before--- Thread[main,5,main]
internal count=7
index count=0
default count=0
orole count=3
ouser count=3
Without save--- Thread[main,5,main]
internal count=11
index count=0
default count=0
orole count=3
ouser count=3
person count=1
company count=1
After save with TX--- Thread[main,5,main]
internal count=11
index count=0
default count=0
orole count=3
ouser count=3
person count=2
company count=1

Thanks for quick reply!
已删除帖子

Luca Garulli

未读,
2010年9月17日 13:28:472010/9/17
收件人 orient-database
I've executed this one and works with the latest fix (SVN 1414). It was the same problem.

Thank you for the report.

bye,
Luca Garulli


On 17 September 2010 18:25, Jani Laakso <jani....@gmail.com> wrote:
Oh, big G ate my last message. Here it goes again..

The above code prints this:



Creating new database
Before--- Thread[main,5,main]
internal count=7
index count=0
default count=0
orole count=3
ouser count=3
Without save--- Thread[main,5,main]
internal count=11
index count=0
default count=0
orole count=3
ouser count=3
person count=1
company count=1
After save with TX--- Thread[main,5,main]
internal count=11
index count=0
default count=0
orole count=3
ouser count=3
person count=2
company count=1

Noticeable thing is that company count is 1 in both cases (should be 2
on the last system out line).


Jani Laakso

未读,
2010年9月18日 02:33:212010/9/18
收件人 OrientDB
Hello,

Confirmed on my environment as well (trunk @ 1414), fixed!

BR Jani

On 17 syys, 20:28, Luca Garulli <l.garu...@orientechnologies.com>
wrote:
> I've executed this one and works with the latest fix (SVN 1414). It was the
> same problem.
>
> Thank you for the report.
>
> bye,
> Luca Garulli
>
回复全部
回复作者
转发
0 个新帖子