# Using transactions with secondary indexes in bdb

**URL:** <https://www.ruby-forum.com/t/using-transactions-with-secondary-indexes-in-bdb/90809>\
**Category:** Ruby\
**Created:** [April 1, 2007, 11:41pm UTC](https://www.ruby-forum.com/t/using-transactions-with-secondary-indexes-in-bdb/90809 "2007-04-01T23:41:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jim\_Cain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c0e974/32.png) [@Jim\_Cain](https://www.ruby-forum.com/u/Jim_Cain)\
**Post date:** [April 1, 2007, 11:41pm UTC](https://www.ruby-forum.com/t/using-transactions-with-secondary-indexes-in-bdb/90809/1 "2007-04-01T23:41:35Z")

</div>

I’m having trouble figuring out how to do transactions. I’m using db  
4.5.40 from Oracle and bdb 0.6.0. Here’s a code snippet:

require ‘bdb’

BDB::Hash.open(‘models.db’, nil, BDB::TRUNCATE) {}  
BDB::Hash.open(‘makes.db’, nil, BDB::TRUNCATE) {}

BDB::Env.open(‘db’, BDB::CREATE | BDB::INIT\_TRANSACTION) do |env|  
models = makes = nil  
env.begin(BDB::TXN\_COMMIT) do |tx|  
models = tx.open\_db(BDB::HASH, ‘models.db’, nil, BDB::CREATE)  
makes = tx.open\_db(BDB::HASH, ‘makes.db’, nil, BDB::CREATE |  
BDB::DUPSORT)  
models.associate(makes) { |sdb, key, value| value }  
end

env.begin(BDB::TXN\_COMMIT) do |tx|  
tx.assoc(models, makes)  
puts ‘===== Before’  
puts ‘----- models’  
models.each { |key, value| puts “#{key} = #{value}” }  
puts ‘----- makes’  
makes.each { |key, value| puts “#{key} = #{value}” }  
end

env.begin(BDB::TXN\_COMMIT) do |tx|  
tx.assoc(models, makes)  
models[‘Civic’] = ‘Honda’  
models[‘Accord’] = ‘Honda’ # this is line 26 where the error is  
occurring  
models[‘S2000’] = ‘Honda’  
models[‘Camry’] = ‘Toyota’  
models[‘Solara’] = ‘Toyota’  
end

env.begin do |tx|  
tx.assoc(models, makes)  
puts ‘===== After’  
puts ‘----- models’  
models.each { |key, value| puts “#{key} = #{value}” }  
puts ‘----- makes’  
makes.each { |key, value| puts “#{key} = #{value}” }  
end

makes.close  
models.close  
end

Now I have no idea if I’m using transactions properly, not to mention  
any of the other various features, but I suspect I’m not since I get  
this output:

===== Before  
----- models  
----- makes  
/home/jim/eclipse/testRuby/test.rb:26:in `close': BUG : current_env not set (BDB::Fatal) from /home/jim/eclipse/testRuby/test.rb:26:in`open’  
from /home/jim/eclipse/testRuby/test.rb:6  
/home/jim/eclipse/testRuby/test.rb:26: [BUG] Segmentation fault  
ruby 1.8.5 (2007-03-13) [i386-linux]

I would greatly appreciate any help that anyone can provide.

Cheers,  
Jim

---

<div class="post-metadata">

**Author:** ![Jim\_Cain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c0e974/32.png) [@Jim\_Cain](https://www.ruby-forum.com/u/Jim_Cain)\
**Post date:** [April 2, 2007, 5:45pm UTC](https://www.ruby-forum.com/t/using-transactions-with-secondary-indexes-in-bdb/90809/2 "2007-04-02T17:45:47Z")

</div>

OK, I figured out that a lot of my previous code was wrong, not even  
considering the transactions, so I removed the transactional stuff and  
got down to this:

require ‘bdb’

BDB::Hash.open(‘models.db’, nil, BDB::CREATE | BDB::TRUNCATE) {}  
BDB::Hash.open(‘makes.db’, nil, BDB::CREATE | BDB::TRUNCATE,  
:set\_flags =\> BDB::DUP | BDB::DUPSORT) {}

BDB::Hash.open(‘models.db’, nil, BDB::CREATE) do |models|  
BDB::Hash.open(‘makes.db’, nil, BDB::CREATE, :set\_flags =\> BDB::DUP  
| BDB::DUPSORT) do |makes|  
models.associate(makes) { |sdb, key, value| value }

```
puts '===== Before'
puts '----- models'
models.each { |key, value| puts "#{key} = #{value}" }
puts '----- makes'
makes.each_primary { |skey, pkey, pvalue| p [skey, pkey, pvalue] }

models['Civic'] = 'Honda'
models['Accord'] = 'Honda'
models['S2000'] = 'Honda'
models['Camry'] = 'Toyota'
models['Solara'] = 'Toyota'

puts '===== After'
puts '----- models'
models.each { |key, value| puts "#{key} = #{value}" }
puts '----- makes'
makes.each_primary { |skey, pkey, pvalue| p [skey, pkey, pvalue] }

```

end  
end

And here is the output, which looks right to me:

===== Before  
----- models  
----- makes  
===== After  
----- models  
Civic = Honda  
Accord = Honda  
Camry = Toyota  
Solara = Toyota  
S2000 = Honda  
----- makes  
[“Honda”, “Accord”, “Honda”]  
[“Honda”, “Civic”, “Honda”]  
[“Honda”, “S2000”, “Honda”]  
[“Toyota”, “Camry”, “Toyota”]  
[“Toyota”, “Solara”, “Toyota”]

Now I just have to figure out the transactional part. I’ll follow up  
on the list once I do.

Cheers,  
Jim

---

<div class="post-metadata">

**Author:** ![Jim\_Cain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c0e974/32.png) [@Jim\_Cain](https://www.ruby-forum.com/u/Jim_Cain)\
**Post date:** [April 2, 2007, 5:51pm UTC](https://www.ruby-forum.com/t/using-transactions-with-secondary-indexes-in-bdb/90809/3 "2007-04-02T17:51:48Z")

</div>

On Tue, 3 Apr 2007, Jim Cain wrote:

> BDB::Hash.open(‘models.db’, nil, BDB::CREATE) do |models|  
> models[‘Civic’] = ‘Honda’  
> end  
> Accord = Honda  
> Now I just have to figure out the transactional part. I’ll follow up  
> on the list once I do.

there are transaction examples in the bdb src - have you looked at that?

-a

---

<div class="post-metadata">

**Author:** ![Jim\_Cain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c0e974/32.png) [@Jim\_Cain](https://www.ruby-forum.com/u/Jim_Cain)\
**Post date:** [April 2, 2007, 9:31pm UTC](https://www.ruby-forum.com/t/using-transactions-with-secondary-indexes-in-bdb/90809/4 "2007-04-02T21:31:17Z")

</div>

On 4/2/07, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> there are transaction examples in the bdb src - have you looked at that?

I looked at the one example file “txn.rb” originally, but I didn’t put  
it all together then. Upon a second look, it’s making a bit more  
sense. In that example, he has:

module BDB  
class ThreadHash \< Hash  
def start(val, num)  
Thread.start do  
self.env.begin(self) do |txn, b1|  
b1.delete\_if do |k, v|  
print “\t#{num} #{k} – #{v}\n”  
k == val  
end  
p “Thread #{num} Pass”  
Thread.pass  
b1.each do |k, v|  
print “\t#{num} #{k} – #{v}\n”  
end  
if num == 1  
txn.abort  
else  
txn.commit  
end  
end  
p “End Thread #{num}”  
end  
end  
end  
end

And then later on he calls #start for each ThreadHash object. I  
suppose the business part of that is:

self.env.begin(self) do |txn, b1|

# …

end

So he’s passing in the ThreadHash object as the only argument to  
#begin, but the docs have this for Env#begin:

begin(flags = 0, db, …) { |txn, db, …| …}

This says that “flags” is the first argument. Maybe that’s where my  
confusion started.

Cheers,  
Jim

---

<div class="post-metadata">

**Author:** ![Jim\_Cain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c0e974/32.png) [@Jim\_Cain](https://www.ruby-forum.com/u/Jim_Cain)\
**Post date:** [April 2, 2007, 11:09pm UTC](https://www.ruby-forum.com/t/using-transactions-with-secondary-indexes-in-bdb/90809/5 "2007-04-02T23:09:49Z")

</div>

I’ve updated my previous example to include transactions:

BDB::Hash.open(‘models.db’, nil, BDB::CREATE | BDB::TRUNCATE) {}  
BDB::Hash.open(‘makes.db’, nil, BDB::CREATE | BDB::TRUNCATE,  
:set\_flags =\> BDB::DUP | BDB::DUPSORT) {}

env = BDB::Env.new(’/home/jim/eclipse/testRuby’,  
BDB::CREATE|BDB::INIT\_TRANSACTION)  
models = env.open\_db(BDB::HASH, ‘models.db’, nil, BDB::CREATE)  
makes = env.open\_db(BDB::HASH, ‘makes.db’, nil, BDB::CREATE,  
:set\_flags =\> BDB::DUP | BDB::DUPSORT)

env.begin(models, makes) do |tx, tx\_models, tx\_makes|  
tx\_models.associate(tx\_makes) { |sdb, key, value| value }  
tx.commit  
end

puts ‘===== Before’  
puts ‘----- models’  
models.each { |key, value| puts “#{key} = #{value}” }  
puts ‘----- makes’  
makes.each\_primary { |skey, pkey, pvalue| p [skey, pkey, pvalue] }

env.begin(BDB::TXN\_COMMIT, models, makes) do |tx, tx\_models, tx\_makes|  
tx\_models[‘Civic’] = ‘Honda’  
tx\_models[‘Accord’] = ‘Honda’  
tx\_models[‘S2000’] = ‘Honda’  
tx\_models[‘Camry’] = ‘Toyota’  
tx\_models[‘Solara’] = ‘Toyota’  
end

env.begin(models, makes) do |tx, tx\_models, tx\_makes|  
puts ‘===== After’  
puts ‘----- models’  
tx\_models.each { |key, value| puts “#{key} = #{value}” }  
puts ‘----- makes’  
tx\_makes.each\_primary { |skey, pkey, pvalue| p [skey, pkey, pvalue]  
}  
end

env.begin(BDB::TXN\_COMMIT, models, makes) do |tx, tx\_models, tx\_makes|  
tx\_makes.close  
tx\_models.close  
end

env.close

Here is the output:

===== Before  
----- models  
----- makes  
===== After  
----- models  
Civic = Honda  
Accord = Honda  
Camry = Toyota  
Solara = Toyota  
S2000 = Honda  
----- makes

It doesn’t appear to be updating the secondary index. What have I done  
wrong?

Cheers,  
Jim
