Offline - Online database syncronising

Pagina: 1
Acties:

  • TukkerTweaker
  • Registratie: November 2001
  • Laatst online: 21-02 23:07
Ik heb een applicatie die data synchroniseert met een online webserver en vervolgens deze data offline in het veld gebruikt, wijzigt, toevoegt, verwijderd. De veranderingen moeten weer gesynchroniseerd worden met de online webserver. Om het een beetje complexer te maken zijn er meerdere clients die niet altijd voor de meeste recente data beschikken voordat er gesynchroniseerd wordt, dus het is mogelijk dat een entity zowel op de server als op de client gewijzigd is.

Welk pattern, relationeel model, methodes, etc. zijn hiervoor bruikbaar?

Tot nu toe hou ik een synchronisatie tabel bij waarbij aangegeven wordt welk object wanneer veranderd is, zowel lokaal als aan de server kant. Die heeft als nadeel dat je niet van alle entities de state kunt bijhouden, alleen van een compleet object.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

TukkerTweaker schreef op donderdag 11 mei 2006 @ 13:37:
Ik heb een applicatie die data synchroniseert met een online webserver en vervolgens deze data offline in het veld gebruikt, wijzigt, toevoegt, verwijderd. De veranderingen moeten weer gesynchroniseerd worden met de online webserver. Om het een beetje complexer te maken zijn er meerdere clients die niet altijd voor de meeste recente data beschikken voordat er gesynchroniseerd wordt, dus het is mogelijk dat een entity zowel op de server als op de client gewijzigd is.

Welk pattern, relationeel model, methodes, etc. zijn hiervoor bruikbaar?
Zoek op offline locking (pessimistic/optimistic).
-optimistic als de kans erg klein is (of als het geen ramp is) dat er een conflict kan ontstaan. Conflicten worden niet voorkomen, alleen gedetecteerd.
-pessimistic als de kans groot is (of als het wel een ramp is) dat er een conflict kan ontstaan. Conflicten worden voorkomen (dus niet alleen gedetecteerd).

In Patterns of Enterprise Application Architecture word dit allemaal erg goed uit de doeken gedaan.

[edit]
Optimistic Offline Lock
Pessimistic Offline Lock

[edit2]
Als je een OR mapper zoals Hibernate gebruikt en versioning activeert (optimistic locking) dan zorgt Hibernate wel voor de rest. Je hoeft zelf dus niet moeilijk te gaan doen.

[edit3]
Voordeel van optimistic locking boven pessimistic is dat optimistic veel beter doorschaalt doordat er minder echte locks zijn. Dus waar een systeem bij een pessimistic lock zou stoppen, kan het doorgaan bij een optimistic lock (met het risico dat je een conflict krijgt, maar het conflict kan in ieder geval wel gedetecteerd worden).

[ Voor 49% gewijzigd door Alarmnummer op 11-05-2006 14:34 ]


  • TukkerTweaker
  • Registratie: November 2001
  • Laatst online: 21-02 23:07
Thanks, hier kan ik wat mee!
Ben voor dat project overgestapt op Hibernate dus ik zal die de locking mogelijkheid daarvoor eens bekijken. Momenteel doe ik ook alleen conflictdetectie waarbij de gebruiker de optie heeft welke actie er uitgevoerd moet worden. Dus optimistic locking is wel een optie.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Optimistic locking activeren binnen Hibernate is super eenvoudig. Het enige wat je hoeft te doen is een version tag in je mapping meegeven (en uiteraard een version column in je table aanmaken)

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

    <hibernate-mapping package="nl.foo.data">

        <class name="User" table="user">

            <id name="id" type="long" unsaved-value="null">
                <column name="id" not-null="true"/>
                <generator class="identity"/>
            </id>

            <version name="version"
                     column="version"
                     type="integer"/>
          
        </class>

</hibernate-mapping>

[ Voor 41% gewijzigd door Alarmnummer op 11-05-2006 18:01 ]


  • dingstje
  • Registratie: Augustus 2002
  • Laatst online: 02-01-2024

If you can't beat them, try harder


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Ik ben trouwens bezig met een blog over isolation issues en webforms. Maar het hele idee erachter laat zich ook uitstekend vertalen naar jouw problematiek. Hier heb je al vast de preview:

*Het is nog niet klaar, typo`s moeten er nog uit. Moet nog wat uitzoek werk doen en verder kan het nog wel wat opgepoetst worden.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
Do you have isolation issues in your webform?

In this blogentry I want to make clear that your webforms could be
subject to isolation issues like lost updates and unrepeatable reads
if no locking is applied. I'm going to explain what causes this
problem and how it can be solved.

In a lot of webapplications webforms are used and it is common
practice that the business transaction for the form spans two system
transactions:
<dir>
       <li>
               the first transaction is executed when the form is shown:
information is retrieved from the database and placed in the form (and
maybe in a session: directly or indirectly).
       </li>
       <li>
               the second transaction is executed when the form is submitted: the
data is processed and placed in the database.
       </li>
</dir>
The reason why the transaction is divided, is because using a single
system transaction requires that transaction to be open from the
moment that the form is shown untill the form is submitted. This
causes a lot of lockcontention and lockcontention reduces scalability
of the application. Imagine what happens when a user decides to make
dinner before he submits.

The problem with this approach is that it could be subject to
isolation issues because no protection is provided after the first
transaction finishes and the second one starts. This makes your system
vonerable to isolation issues like lost updates and unrepeatable
reads. The biggest problem with these types of errors is that they are
very hard to detect and to reproduce. So some users experience strange
problems but the code doesn't show any bugs.

That is why you need some kind of locking mechanism that doesn't rely
on an active transaction. This type of locking is called offline
locking. There are two different approaches:
<dir>
       <li>pessimistic offline locking</li>
       <li>optimistic offline locking</li>
</dir>

<h3>Optimistic Offline Locking</h3>
With the optimistic approach you are optimistic about the fact that
the chance is very small that a different transaction is going to
update the same record(s) in the period that the current record is
between the 2 transactions and that the consequences of the conflict
are not that bad.

It works like this: a version is added to the record(s) and when the
record is read, the version is copied to the object. When the object
is submitted to the database, the version of the object can be checked
with the version of the record.  If a different transaction has
modified that record, the version in the database is higher and you
know the 'lock' has failed. That is how optimistic locking is able to
detect conflicts.

The advantage of optimistic locking is that it scales better (because
it is subject to less lockcontention) and that it is quite easy to
implement. If you store the objects in the session of the webcontainer
and use a modern OR-mapper like Hibernate, you don't have to do
anything special because Hibernate will check the versions for you (if
you have actived optimistic locking). If you are using a long
(hibernate) session the versions can be checked when the session is
reattached to the db. (checken).

If you don't want to rely on the session of your webcontainer (because
it also reduced scalability) you could store the information in a
hidden field in the form. I think you have to realize that this could
be a security risk because someone could alter the version manually.
If you think this could be an issue, you could encrypt the version
before placing it.

<h3>Pessimistic Offline Locking</h3>

<h3>Being pragmatic</h3>
In some cases you need to be pragmatic. Ofcourse it technically is
better to do locking, but it takes extra time. And if the chances of
conflicts are small (eg: a forum user that is updating his email
address) and the consequences are small, it would acceptable to skip
the locking. But I think it is important that you realize the
consequences of this approach and that you are able to justify it.

If you want to read more about this subject I recommend "Patterns of
Enterpise Application Architecture" from Martin Fowler. In the
"Concurrency" chapter you can find a lot more information about this 
interresting but tricky subject.


En voor de liefhebbers:
ik ben ook bezig met een post of issues binnen 1 controller call. En ik ben ook bezig met een blogpost of isolation issues binnen 1 business call icm Spring/Hibernate. Volgens mij heb ik dan de meest belangrijke isolation issues dan afgedekt voor de presentation layer.

[edit]
Ik heb de blogpost dit weekend afgerond:
Do you have isolation issues in your webform?

[ Voor 22% gewijzigd door Alarmnummer op 15-05-2006 10:06 ]

Pagina: 1