Difference between revisions of "Talk:Transactions"

(External example)
Line 4: Line 4:
  
 
I think we need to see some examples (well, I do for one).
 
I think we need to see some examples (well, I do for one).
 
== Examples ==
 
The main thing to remember is that the proposal states that all features calls are asynchronous.
 
 
Transactions are assured with transactional memory, probably implemented as software transactional memory.
 
----------------
 
Example of transaction:<br/>
 
feature<br/>
 
correct_removal(container: DISPENSER) is<br/>
 
&nbsp;transaction  --  This is a transaction so it is assured to be atomic and isolated<br/>
 
&nbsp;&nbsp;if<br/>
 
&nbsp;&nbsp;&nbsp;not(container.is_empty)<br/>
 
&nbsp;&nbsp;then<br/>
 
&nbsp;&nbsp;&nbsp;container.remove<br/>
 
&nbsp;&nbsp;end<br/>
 
&nbsp;end<br/>
 
 
This feature is assured to be correct because is is isolated and atomic with respect to the system.  If the container has been modified between the call to is_empty and remove, the feature would be aborted and retried.
 
-----------------
 
 
feature<br/>
 
incorrect_removal(container: DISPENSER) is<br/>
 
&nbsp;do<br/>
 
&nbsp;&nbsp;if<br/>
 
&nbsp;&nbsp;&nbsp;not(container.is_empty)<br/>
 
&nbsp;&nbsp;then<br/>
 
&nbsp;&nbsp;&nbsp;container.remove<br/>
 
&nbsp;&nbsp;end<br/>
 
&nbsp;end<br/>
 
 
This is the standard example of concurrency issues with preconditions.  The container can change between the call to is_empty and remove.  Using transactions avoids this.
 
----------------
 
 
Example of concurrency:<br/>
 
feature<br/>
 
write_all_files is<br/>
 
&nbsp;do<br/>
 
&nbsp;&nbsp;write_file_1<br/>
 
&nbsp;&nbsp;write_file_2<br/>
 
&nbsp;&nbsp;write_file_3<br/>
 
&nbsp;&nbsp;write_file_4<br/>
 
&nbsp;end<br/>
 
 
Since all feature calls would be asynchronous, the four write_file features could be executed in parallel if the runtime decides to do so.  This is not a transaction so isolation across these calls is not assured.
 
----------------
 
 
feature<br/>
 
write_file is<br/>
 
&nbsp;external<br/>
 
&nbsp;&nbsp;"operating_system_write"<br/>
 
&nbsp;abort<br/>
 
&nbsp;&nbsp;"operating_system_abort"<br/>
 
&nbsp;commit<br/>
 
&nbsp;&nbsp;"operating_system_commit"<br/>
 
 
This is how transactional features can be mapped on to external function calls that support transactional operations
 
----------------
 
 
feature<br/>
 
source: DISPENSER[ANY] --Where items are taken from<br/>
 
destination: DISPENSER[ANY] -- where items are put after processing<br/>
 
running: BOOLEAN -- Flag to stop processing<br/>
 
 
consumer is<br/>
 
&nbsp;do<br/>
 
&nbsp;&nbsp;from<br/>
 
&nbsp;&nbsp;until<br/>
 
&nbsp;&nbsp;&nbsp;not (running)<br/>
 
&nbsp;&nbsp;loop --This loop will spawn multiple threads, microthreads, hyperthreads, or whatever the implementation is and runtime chooses, all processing a single item.<br/>
 
&nbsp;&nbsp;&nbsp;process_single_item<br/>
 
&nbsp;&nbsp;end<br/>
 
&nbsp;end<br/>
 
<br/>
 
process_single_item is<br/>
 
&nbsp;local<br/>
 
&nbsp;&nbsp;item: ANY<br/>
 
&nbsp;transaction --Since this is a transaction,  accessing the container is safe even when run concurrently.<br/>
 
&nbsp;&nbsp;if<br/>
 
&nbsp;&nbsp;&nbsp;not source.is_empty<br/>
 
&nbsp;&nbsp;then<br/>
 
&nbsp;&nbsp;&nbsp;item := source.item<br/>
 
&nbsp;&nbsp;&nbsp;source.remove<br/>
 
&nbsp;&nbsp;&nbsp;io.put_string(item.to_string)<br/>
 
&nbsp;&nbsp;&nbsp;destination.put(item)<br/>
 
&nbsp;&nbsp;end<br/>
 
&nbsp;end<br/>
 
<br/>
 
---------------
 
Legacy externals example
 
 
feature<br/>
 
use_legacy_external(item: LEGACY_ITEM) is<br/>
 
&nbsp;do<br/>
 
&nbsp;&nbsp;print_item(item)<br/>
 
&nbsp;&nbsp;log_item(item)<br/>
 
&nbsp;&nbsp;--At this point the runtime will block until print_item and log_item have both committed, it will ensure nothing is running in the system and then run the external item serially.  This is the non-concurrent way to ensure something executes as a transaction, isolated and atomic.<br/>
 
&nbsp;&nbsp;use_item(item)<br/>
 
&nbsp;end<br/>
 
<br/>
 
use_item(item: LEGACY_ITEM) is<br/>
 
&nbsp;external<br/>
 
&nbsp;&nbsp;"..."<br/>
 
&nbsp;end<br/>
 
<br/>
 
print_item(item: LEGACY_ITEM) is<br/>
 
&nbsp;do<br/>
 
&nbsp;&nbsp;...<br/>
 
&nbsp;end<br/>
 
<br/>
 
log_item(item: LEGACY_ITEM) is<br/>
 
&nbsp;do<br/>
 
&nbsp;&nbsp;...<br/>
 
&nbsp;end<br/>
 

Revision as of 11:38, 6 April 2007

Discussion of the feasibility and desirability of implementing transactional concurrency in Eiffel.

Examples please

I think we need to see some examples (well, I do for one).